sip-lab 1.22.0 → 1.23.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/README.md +3 -2
- package/build_deps.sh +2 -1
- package/index.js +1 -0
- package/package.json +1 -1
- package/prebuilds/linux-x64/sip-lab.node +0 -0
- package/samples/start_play_wav_with_end_of_file_event.js +269 -0
- package/samples/start_play_wav_with_no_loop.js +257 -0
- package/samples/tcp_and_extra_headers.js +3 -0
- package/samples/text_to_speech.js +22 -3
- package/src/addon.cpp +35 -0
- package/src/event_templates.cpp +14 -7
- package/src/event_templates.hpp +4 -0
- package/src/pjmedia/include/pjmedia/flite_port.h +10 -4
- package/src/pjmedia/src/pjmedia/flite_port.c +87 -18
- package/src/pjmedia/src/pjmedia/pocketsphinx_port.c +150 -0
- package/src/sip.cpp +326 -251
- package/src/sip.hpp +2 -0
package/src/sip.cpp
CHANGED
|
@@ -618,11 +618,11 @@ static void build_stream_stat(ostringstream &oss, pjmedia_rtcp_stat *stat,
|
|
|
618
618
|
|
|
619
619
|
bool prepare_tonegen(Call *call, AudioEndpoint *ae);
|
|
620
620
|
bool prepare_dtmfdet(Call *call, AudioEndpoint *ae);
|
|
621
|
-
bool prepare_wav_player(Call *c, AudioEndpoint *ae, const char *file);
|
|
621
|
+
bool prepare_wav_player(Call *c, AudioEndpoint *ae, const char *file, unsigned flags, bool end_of_file_event);
|
|
622
622
|
bool prepare_wav_writer(Call *c, AudioEndpoint *ae, const char *file);
|
|
623
623
|
bool prepare_fax(Call *c, AudioEndpoint *ae, bool is_sender, const char *file,
|
|
624
624
|
unsigned flags);
|
|
625
|
-
bool prepare_flite(Call *c, AudioEndpoint *ae, const char *voice);
|
|
625
|
+
bool prepare_flite(Call *c, AudioEndpoint *ae, const char *voice, bool end_of_speech_event);
|
|
626
626
|
|
|
627
627
|
void prepare_error_event(ostringstream *oss, char *scope, char *details);
|
|
628
628
|
// void prepare_pjsipcall_error_event(ostringstream *oss, char *scope, char
|
|
@@ -641,7 +641,7 @@ typedef pj_status_t (*audio_endpoint_stop_op_t)(Call *call, AudioEndpoint *ae);
|
|
|
641
641
|
pj_status_t audio_endpoint_stop_play_wav(Call *call, AudioEndpoint *ae);
|
|
642
642
|
pj_status_t audio_endpoint_stop_record_wav(Call *call, AudioEndpoint *ae);
|
|
643
643
|
pj_status_t audio_endpoint_stop_fax(Call *call, AudioEndpoint *ae);
|
|
644
|
-
pj_status_t
|
|
644
|
+
pj_status_t audio_endpoint_stop_speech_synth(Call *call, AudioEndpoint *ae);
|
|
645
645
|
|
|
646
646
|
static pjsip_module mod_tester = {
|
|
647
647
|
NULL,
|
|
@@ -851,7 +851,7 @@ static void on_inband_dtmf(pjmedia_port *port, void *user_data, char digit) {
|
|
|
851
851
|
ae->last_digit_timestamp[mode] = ms_timestamp();
|
|
852
852
|
PJW_UNLOCK();
|
|
853
853
|
} else {
|
|
854
|
-
char evt[
|
|
854
|
+
char evt[1024];
|
|
855
855
|
make_evt_dtmf(evt, sizeof(evt), call_id, 1, &d, mode, media_id);
|
|
856
856
|
dispatch_event(evt);
|
|
857
857
|
}
|
|
@@ -868,11 +868,44 @@ static void on_fax_result(pjmedia_port *port, void *user_data, int result) {
|
|
|
868
868
|
return;
|
|
869
869
|
}
|
|
870
870
|
|
|
871
|
-
char evt[
|
|
871
|
+
char evt[1024];
|
|
872
872
|
make_evt_fax_result(evt, sizeof(evt), call_id, result);
|
|
873
873
|
dispatch_event(evt);
|
|
874
874
|
}
|
|
875
875
|
|
|
876
|
+
static void on_end_of_file(pjmedia_port *port, void *user_data) {
|
|
877
|
+
if (g_shutting_down)
|
|
878
|
+
return;
|
|
879
|
+
|
|
880
|
+
long call_id;
|
|
881
|
+
if (!g_call_ids.get_id((long)user_data, call_id)) {
|
|
882
|
+
printf(
|
|
883
|
+
"on_end_of_file: Failed to get call_id. Event will not be notified.\n");
|
|
884
|
+
return;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
char evt[1024];
|
|
888
|
+
make_evt_end_of_file(evt, sizeof(evt), call_id);
|
|
889
|
+
dispatch_event(evt);
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
static void on_end_of_speech(pjmedia_port *port, void *user_data) {
|
|
893
|
+
if (g_shutting_down)
|
|
894
|
+
return;
|
|
895
|
+
|
|
896
|
+
long call_id;
|
|
897
|
+
if (!g_call_ids.get_id((long)user_data, call_id)) {
|
|
898
|
+
printf(
|
|
899
|
+
"on_end_of_speech: Failed to get call_id. Event will not be notified.\n");
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
char evt[1024];
|
|
904
|
+
make_evt_end_of_speech(evt, sizeof(evt), call_id);
|
|
905
|
+
dispatch_event(evt);
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
|
|
876
909
|
void dispatch_event(const char *evt) {
|
|
877
910
|
addon_log(L_DBG, "dispach_event called with evt=%s\n", evt);
|
|
878
911
|
// g_event_sink(evt);
|
|
@@ -3090,7 +3123,6 @@ pj_status_t send_dtmf(Call *call, const char *digits, int mode) {
|
|
|
3090
3123
|
return PJ_SUCCESS;
|
|
3091
3124
|
}
|
|
3092
3125
|
|
|
3093
|
-
// int pjw_call_send_dtmf(long call_id, const char *digits, int mode)
|
|
3094
3126
|
int pjw_call_send_dtmf(long call_id, const char *json) {
|
|
3095
3127
|
#define MAX_LENGTH \
|
|
3096
3128
|
31 // pjsip allows for 31 digits (inband allows for 32 digits)
|
|
@@ -3098,32 +3130,40 @@ int pjw_call_send_dtmf(long call_id, const char *json) {
|
|
|
3098
3130
|
PJW_LOCK();
|
|
3099
3131
|
clear_error();
|
|
3100
3132
|
|
|
3133
|
+
Call *call;
|
|
3134
|
+
|
|
3135
|
+
pj_status_t status;
|
|
3136
|
+
|
|
3101
3137
|
long val;
|
|
3138
|
+
|
|
3102
3139
|
char *digits;
|
|
3103
3140
|
int mode = 0;
|
|
3104
|
-
;
|
|
3105
3141
|
|
|
3106
|
-
|
|
3142
|
+
MediaEndpoint *me;
|
|
3143
|
+
AudioEndpoint *ae;
|
|
3144
|
+
int res;
|
|
3145
|
+
|
|
3146
|
+
int media_id = -1;
|
|
3107
3147
|
|
|
3108
3148
|
char buffer[MAX_JSON_INPUT];
|
|
3109
3149
|
|
|
3110
3150
|
Document document;
|
|
3111
3151
|
|
|
3112
|
-
const char *valid_params[] = {"digits", "mode", ""};
|
|
3152
|
+
const char *valid_params[] = {"digits", "mode", "media_id", ""};
|
|
3113
3153
|
|
|
3114
|
-
if (!
|
|
3154
|
+
if (!g_call_ids.get(call_id, val)) {
|
|
3155
|
+
set_error("Invalid call_id");
|
|
3115
3156
|
goto out;
|
|
3116
3157
|
}
|
|
3158
|
+
call = (Call *)val;
|
|
3117
3159
|
|
|
3118
|
-
if (!
|
|
3160
|
+
if (!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
3119
3161
|
goto out;
|
|
3120
3162
|
}
|
|
3121
3163
|
|
|
3122
|
-
if (!
|
|
3123
|
-
set_error("Invalid call_id");
|
|
3164
|
+
if (!validate_params(document, valid_params)) {
|
|
3124
3165
|
goto out;
|
|
3125
3166
|
}
|
|
3126
|
-
call = (Call *)val;
|
|
3127
3167
|
|
|
3128
3168
|
if (json_get_string_param(document, "digits", false, &digits) <= 0) {
|
|
3129
3169
|
goto out;
|
|
@@ -3169,7 +3209,38 @@ int pjw_call_send_dtmf(long call_id, const char *json) {
|
|
|
3169
3209
|
adjusted_digits[len] = 0;
|
|
3170
3210
|
// addon_log(L_DBG, "adjusted_digits >>%s<<\n", adjusted_digits);
|
|
3171
3211
|
|
|
3172
|
-
|
|
3212
|
+
res = json_get_int_param(document, "media_id", true, &media_id);
|
|
3213
|
+
if (res <= 0) {
|
|
3214
|
+
goto out;
|
|
3215
|
+
}
|
|
3216
|
+
|
|
3217
|
+
if (NOT_FOUND_OPTIONAL == res) {
|
|
3218
|
+
// send_dtmf to all audio endpoints
|
|
3219
|
+
status = send_dtmf(call, adjusted_digits, mode);
|
|
3220
|
+
if (status != PJ_SUCCESS) {
|
|
3221
|
+
goto out;
|
|
3222
|
+
}
|
|
3223
|
+
} else {
|
|
3224
|
+
// send_dtmf to specified media_id
|
|
3225
|
+
|
|
3226
|
+
if (media_id >= call->media_count) {
|
|
3227
|
+
set_error("invalid media_id");
|
|
3228
|
+
goto out;
|
|
3229
|
+
}
|
|
3230
|
+
|
|
3231
|
+
me = (MediaEndpoint *)call->media[media_id];
|
|
3232
|
+
if (ENDPOINT_TYPE_AUDIO != me->type) {
|
|
3233
|
+
set_error("invalid media_id non audio");
|
|
3234
|
+
goto out;
|
|
3235
|
+
}
|
|
3236
|
+
|
|
3237
|
+
ae = (AudioEndpoint *)me->endpoint.audio;
|
|
3238
|
+
|
|
3239
|
+
status = audio_endpoint_send_dtmf(call, ae, digits, mode);
|
|
3240
|
+
if (status != PJ_SUCCESS) {
|
|
3241
|
+
goto out;
|
|
3242
|
+
}
|
|
3243
|
+
}
|
|
3173
3244
|
|
|
3174
3245
|
out:
|
|
3175
3246
|
PJW_UNLOCK();
|
|
@@ -3443,7 +3514,15 @@ int count_media_by_type(Call *call, int type) {
|
|
|
3443
3514
|
return total;
|
|
3444
3515
|
}
|
|
3445
3516
|
|
|
3446
|
-
|
|
3517
|
+
int get_first_media_id_by_type(Call *call, int type) {
|
|
3518
|
+
for (int i = 0; i < call->media_count; i++) {
|
|
3519
|
+
MediaEndpoint *me = (MediaEndpoint *)call->media[i];
|
|
3520
|
+
if (type == me->type)
|
|
3521
|
+
return i;
|
|
3522
|
+
}
|
|
3523
|
+
return -1;
|
|
3524
|
+
}
|
|
3525
|
+
|
|
3447
3526
|
int pjw_call_start_record_wav(long call_id, const char *json) {
|
|
3448
3527
|
PJW_LOCK();
|
|
3449
3528
|
clear_error();
|
|
@@ -3452,7 +3531,7 @@ int pjw_call_start_record_wav(long call_id, const char *json) {
|
|
|
3452
3531
|
Call *call;
|
|
3453
3532
|
pj_status_t status;
|
|
3454
3533
|
|
|
3455
|
-
|
|
3534
|
+
int media_id = -1;
|
|
3456
3535
|
|
|
3457
3536
|
MediaEndpoint *me;
|
|
3458
3537
|
AudioEndpoint *ae;
|
|
@@ -3497,7 +3576,13 @@ int pjw_call_start_record_wav(long call_id, const char *json) {
|
|
|
3497
3576
|
}
|
|
3498
3577
|
|
|
3499
3578
|
if (ae_count > 1) {
|
|
3500
|
-
if (
|
|
3579
|
+
if (json_get_int_param(document, "media_id", false, &media_id) <= 0) {
|
|
3580
|
+
goto out;
|
|
3581
|
+
}
|
|
3582
|
+
} else {
|
|
3583
|
+
media_id = get_first_media_id_by_type(call, ENDPOINT_TYPE_AUDIO);
|
|
3584
|
+
if(media_id < 0) {
|
|
3585
|
+
set_error("could not resolve media_id");
|
|
3501
3586
|
goto out;
|
|
3502
3587
|
}
|
|
3503
3588
|
}
|
|
@@ -3541,7 +3626,7 @@ out:
|
|
|
3541
3626
|
}
|
|
3542
3627
|
|
|
3543
3628
|
pj_status_t audio_endpoint_start_play_wav(Call *call, AudioEndpoint *ae,
|
|
3544
|
-
const char *file) {
|
|
3629
|
+
const char *file, unsigned flags, bool end_of_file_event) {
|
|
3545
3630
|
pj_status_t status;
|
|
3546
3631
|
|
|
3547
3632
|
if(!ae->stream_cbp.port) {
|
|
@@ -3555,14 +3640,34 @@ pj_status_t audio_endpoint_start_play_wav(Call *call, AudioEndpoint *ae,
|
|
|
3555
3640
|
return -1;
|
|
3556
3641
|
}
|
|
3557
3642
|
|
|
3558
|
-
if (!prepare_wav_player(call, ae, file)) {
|
|
3643
|
+
if (!prepare_wav_player(call, ae, file, flags, end_of_file_event)) {
|
|
3644
|
+
return -1;
|
|
3645
|
+
}
|
|
3646
|
+
|
|
3647
|
+
return PJ_SUCCESS;
|
|
3648
|
+
}
|
|
3649
|
+
|
|
3650
|
+
pj_status_t audio_endpoint_start_fax(Call *call, AudioEndpoint *ae, bool is_sender, char *file, unsigned flags) {
|
|
3651
|
+
pj_status_t status;
|
|
3652
|
+
|
|
3653
|
+
if(!ae->stream_cbp.port) {
|
|
3654
|
+
set_error("stream port is not ready yet");
|
|
3655
|
+
return -1;
|
|
3656
|
+
}
|
|
3657
|
+
|
|
3658
|
+
// First stop and destroy existing port.
|
|
3659
|
+
status = audio_endpoint_stop_fax(call, ae);
|
|
3660
|
+
if(status != PJ_SUCCESS) {
|
|
3661
|
+
return -1;
|
|
3662
|
+
}
|
|
3663
|
+
|
|
3664
|
+
if (!prepare_fax(call, ae, is_sender, file, flags)) {
|
|
3559
3665
|
return -1;
|
|
3560
3666
|
}
|
|
3561
3667
|
|
|
3562
3668
|
return PJ_SUCCESS;
|
|
3563
3669
|
}
|
|
3564
3670
|
|
|
3565
|
-
// int pjw_call_start_play_wav(long call_id, const char *file)
|
|
3566
3671
|
int pjw_call_start_play_wav(long call_id, const char *json) {
|
|
3567
3672
|
PJW_LOCK();
|
|
3568
3673
|
clear_error();
|
|
@@ -3573,16 +3678,25 @@ int pjw_call_start_play_wav(long call_id, const char *json) {
|
|
|
3573
3678
|
MediaEndpoint *me;
|
|
3574
3679
|
AudioEndpoint *ae;
|
|
3575
3680
|
int ae_count;
|
|
3681
|
+
int res;
|
|
3576
3682
|
|
|
3577
|
-
|
|
3683
|
+
int media_id = -1;
|
|
3578
3684
|
|
|
3579
3685
|
char *file;
|
|
3580
3686
|
|
|
3687
|
+
unsigned flags = 0;
|
|
3688
|
+
|
|
3689
|
+
bool end_of_file_event = false;
|
|
3690
|
+
|
|
3691
|
+
bool no_loop = false;
|
|
3692
|
+
|
|
3581
3693
|
char buffer[MAX_JSON_INPUT];
|
|
3582
3694
|
|
|
3695
|
+
pj_status_t status;
|
|
3696
|
+
|
|
3583
3697
|
Document document;
|
|
3584
3698
|
|
|
3585
|
-
const char *valid_params[] = {"file", "media_id", ""};
|
|
3699
|
+
const char *valid_params[] = {"file", "media_id", "end_of_file_event", "no_loop", ""};
|
|
3586
3700
|
|
|
3587
3701
|
if (!g_call_ids.get(call_id, val)) {
|
|
3588
3702
|
set_error("Invalid call_id");
|
|
@@ -3614,26 +3728,49 @@ int pjw_call_start_play_wav(long call_id, const char *json) {
|
|
|
3614
3728
|
goto out;
|
|
3615
3729
|
}
|
|
3616
3730
|
|
|
3617
|
-
if (
|
|
3618
|
-
|
|
3619
|
-
goto out;
|
|
3620
|
-
}
|
|
3731
|
+
if (json_get_bool_param(document, "end_of_file_event", true, &end_of_file_event) <= 0) {
|
|
3732
|
+
goto out;
|
|
3621
3733
|
}
|
|
3622
3734
|
|
|
3623
|
-
if ((
|
|
3624
|
-
set_error("invalid media_id");
|
|
3735
|
+
if (json_get_bool_param(document, "no_loop", true, &no_loop) <= 0) {
|
|
3625
3736
|
goto out;
|
|
3626
3737
|
}
|
|
3627
3738
|
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3739
|
+
if(no_loop) {
|
|
3740
|
+
flags |= PJMEDIA_FILE_NO_LOOP;
|
|
3741
|
+
}
|
|
3742
|
+
|
|
3743
|
+
res = json_get_int_param(document, "media_id", true, &media_id);
|
|
3744
|
+
if (res <= 0) {
|
|
3631
3745
|
goto out;
|
|
3632
3746
|
}
|
|
3633
3747
|
|
|
3634
|
-
|
|
3748
|
+
if (NOT_FOUND_OPTIONAL == res) {
|
|
3749
|
+
// start on all audio media endpoints
|
|
3750
|
+
for (int i = 0; i < call->media_count; i++) {
|
|
3751
|
+
MediaEndpoint *me = (MediaEndpoint *)call->media[i];
|
|
3752
|
+
if (me->type == ENDPOINT_TYPE_AUDIO) {
|
|
3753
|
+
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
3754
|
+
status = audio_endpoint_start_play_wav(call, ae, file, flags, end_of_file_event);
|
|
3755
|
+
if (status != PJ_SUCCESS) goto out;
|
|
3756
|
+
}
|
|
3757
|
+
}
|
|
3758
|
+
} else {
|
|
3759
|
+
if (media_id >= call->media_count) {
|
|
3760
|
+
set_error("invalid media_id");
|
|
3761
|
+
goto out;
|
|
3762
|
+
}
|
|
3635
3763
|
|
|
3636
|
-
|
|
3764
|
+
me = (MediaEndpoint *)call->media[media_id];
|
|
3765
|
+
if (ENDPOINT_TYPE_AUDIO != me->type) {
|
|
3766
|
+
set_error("media_endpoint is not audio endpoint");
|
|
3767
|
+
goto out;
|
|
3768
|
+
}
|
|
3769
|
+
|
|
3770
|
+
ae = (AudioEndpoint *)me->endpoint.audio;
|
|
3771
|
+
|
|
3772
|
+
audio_endpoint_start_play_wav(call, ae, file, flags, end_of_file_event);
|
|
3773
|
+
}
|
|
3637
3774
|
|
|
3638
3775
|
out:
|
|
3639
3776
|
PJW_UNLOCK();
|
|
@@ -3644,7 +3781,7 @@ out:
|
|
|
3644
3781
|
return 0;
|
|
3645
3782
|
}
|
|
3646
3783
|
|
|
3647
|
-
pj_status_t audio_endpoint_start_speech_synth(Call *call, AudioEndpoint *ae, const char * voice, const char *text) {
|
|
3784
|
+
pj_status_t audio_endpoint_start_speech_synth(Call *call, AudioEndpoint *ae, const char * voice, const char *text, unsigned flags, bool end_of_speech_event) {
|
|
3648
3785
|
pj_status_t status;
|
|
3649
3786
|
|
|
3650
3787
|
if(!ae->stream_cbp.port) {
|
|
@@ -3653,16 +3790,16 @@ pj_status_t audio_endpoint_start_speech_synth(Call *call, AudioEndpoint *ae, con
|
|
|
3653
3790
|
}
|
|
3654
3791
|
|
|
3655
3792
|
// First stop and destroy existing flite port.
|
|
3656
|
-
status =
|
|
3793
|
+
status = audio_endpoint_stop_speech_synth(call, ae);
|
|
3657
3794
|
if(status != PJ_SUCCESS) {
|
|
3658
3795
|
return -1;
|
|
3659
3796
|
}
|
|
3660
3797
|
|
|
3661
|
-
if (!prepare_flite(call, ae, voice)) {
|
|
3798
|
+
if (!prepare_flite(call, ae, voice, end_of_speech_event)) {
|
|
3662
3799
|
return -1;
|
|
3663
3800
|
}
|
|
3664
3801
|
|
|
3665
|
-
pjmedia_flite_port_speak(ae->flite_cbp.port, text,
|
|
3802
|
+
pjmedia_flite_port_speak(ae->flite_cbp.port, text, flags);
|
|
3666
3803
|
|
|
3667
3804
|
return PJ_SUCCESS;
|
|
3668
3805
|
}
|
|
@@ -3674,21 +3811,30 @@ int pjw_call_start_speech_synth(long call_id, const char *json) {
|
|
|
3674
3811
|
long val;
|
|
3675
3812
|
Call *call;
|
|
3676
3813
|
|
|
3814
|
+
pj_status_t status;
|
|
3815
|
+
|
|
3677
3816
|
MediaEndpoint *me;
|
|
3678
3817
|
AudioEndpoint *ae;
|
|
3679
3818
|
int ae_count;
|
|
3819
|
+
int res;
|
|
3680
3820
|
|
|
3681
|
-
|
|
3821
|
+
int media_id = -1;
|
|
3682
3822
|
|
|
3683
3823
|
char *voice;
|
|
3684
3824
|
|
|
3685
3825
|
char *text;
|
|
3686
3826
|
|
|
3827
|
+
bool end_of_speech_event = false;
|
|
3828
|
+
|
|
3829
|
+
unsigned flags = 0;
|
|
3830
|
+
|
|
3831
|
+
bool no_loop = false;
|
|
3832
|
+
|
|
3687
3833
|
char buffer[MAX_JSON_INPUT];
|
|
3688
3834
|
|
|
3689
3835
|
Document document;
|
|
3690
3836
|
|
|
3691
|
-
const char *valid_params[] = {"voice", "text", "media_id", ""};
|
|
3837
|
+
const char *valid_params[] = {"voice", "text", "media_id", "end_of_speech_event", "no_loop", ""};
|
|
3692
3838
|
|
|
3693
3839
|
if (!g_call_ids.get(call_id, val)) {
|
|
3694
3840
|
set_error("Invalid call_id");
|
|
@@ -3729,26 +3875,49 @@ int pjw_call_start_speech_synth(long call_id, const char *json) {
|
|
|
3729
3875
|
goto out;
|
|
3730
3876
|
}
|
|
3731
3877
|
|
|
3732
|
-
if (
|
|
3733
|
-
|
|
3734
|
-
goto out;
|
|
3735
|
-
}
|
|
3878
|
+
if (json_get_bool_param(document, "end_of_speech_event", true, &end_of_speech_event) <= 0) {
|
|
3879
|
+
goto out;
|
|
3736
3880
|
}
|
|
3737
3881
|
|
|
3738
|
-
if ((
|
|
3739
|
-
set_error("invalid media_id");
|
|
3882
|
+
if (json_get_bool_param(document, "no_loop", true, &no_loop) <= 0) {
|
|
3740
3883
|
goto out;
|
|
3741
3884
|
}
|
|
3742
3885
|
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3886
|
+
if(no_loop) {
|
|
3887
|
+
flags |= PJMEDIA_SPEECH_NO_LOOP;
|
|
3888
|
+
}
|
|
3889
|
+
|
|
3890
|
+
res = json_get_int_param(document, "media_id", true, &media_id);
|
|
3891
|
+
if (res <= 0) {
|
|
3746
3892
|
goto out;
|
|
3747
3893
|
}
|
|
3748
3894
|
|
|
3749
|
-
|
|
3895
|
+
if (NOT_FOUND_OPTIONAL == res) {
|
|
3896
|
+
// start on all audio media endpoints
|
|
3897
|
+
for (int i = 0; i < call->media_count; i++) {
|
|
3898
|
+
MediaEndpoint *me = (MediaEndpoint *)call->media[i];
|
|
3899
|
+
if (me->type == ENDPOINT_TYPE_AUDIO) {
|
|
3900
|
+
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
3901
|
+
status = audio_endpoint_start_speech_synth(call, ae, voice, text, flags, end_of_speech_event);
|
|
3902
|
+
if (status != PJ_SUCCESS) goto out;
|
|
3903
|
+
}
|
|
3904
|
+
}
|
|
3905
|
+
} else {
|
|
3906
|
+
if ((int)media_id >= call->media_count) {
|
|
3907
|
+
set_error("invalid media_id");
|
|
3908
|
+
goto out;
|
|
3909
|
+
}
|
|
3910
|
+
|
|
3911
|
+
me = (MediaEndpoint *)call->media[media_id];
|
|
3912
|
+
if (ENDPOINT_TYPE_AUDIO != me->type) {
|
|
3913
|
+
set_error("media_endpoint is not audio endpoint");
|
|
3914
|
+
goto out;
|
|
3915
|
+
}
|
|
3916
|
+
|
|
3917
|
+
ae = (AudioEndpoint *)me->endpoint.audio;
|
|
3750
3918
|
|
|
3751
|
-
|
|
3919
|
+
audio_endpoint_start_speech_synth(call, ae, voice, text, flags, end_of_speech_event);
|
|
3920
|
+
}
|
|
3752
3921
|
|
|
3753
3922
|
out:
|
|
3754
3923
|
PJW_UNLOCK();
|
|
@@ -3759,13 +3928,9 @@ out:
|
|
|
3759
3928
|
return 0;
|
|
3760
3929
|
}
|
|
3761
3930
|
|
|
3762
|
-
pj_status_t
|
|
3763
|
-
return audio_endpoint_remove_port(call, &ae->flite_cbp);
|
|
3764
|
-
}
|
|
3765
|
-
|
|
3766
|
-
pj_status_t call_stop_audio_endpoints_op(Call *call,
|
|
3931
|
+
pj_status_t call_stop_op_on_all_audio_endpoints(Call *call,
|
|
3767
3932
|
audio_endpoint_stop_op_t op) {
|
|
3768
|
-
addon_log(L_DBG, "
|
|
3933
|
+
addon_log(L_DBG, "call_stop_op_on_audio_endpoints media_count=%d\n",
|
|
3769
3934
|
call->media_count);
|
|
3770
3935
|
pj_status_t status;
|
|
3771
3936
|
for (int i = 0; i < call->media_count; i++) {
|
|
@@ -3784,11 +3949,7 @@ pj_status_t call_stop_audio_endpoints_op(Call *call,
|
|
|
3784
3949
|
return PJ_SUCCESS;
|
|
3785
3950
|
}
|
|
3786
3951
|
|
|
3787
|
-
|
|
3788
|
-
return audio_endpoint_remove_port(call, &ae->wav_player_cbp);
|
|
3789
|
-
}
|
|
3790
|
-
|
|
3791
|
-
int pjw_call_stop_play_wav(long call_id, const char *json) {
|
|
3952
|
+
int audio_endpoint_stop_op(long call_id, const char *json, audio_endpoint_stop_op_t op) {
|
|
3792
3953
|
PJW_LOCK();
|
|
3793
3954
|
clear_error();
|
|
3794
3955
|
|
|
@@ -3802,7 +3963,7 @@ int pjw_call_stop_play_wav(long call_id, const char *json) {
|
|
|
3802
3963
|
AudioEndpoint *ae;
|
|
3803
3964
|
int res;
|
|
3804
3965
|
|
|
3805
|
-
|
|
3966
|
+
int media_id = -1;
|
|
3806
3967
|
|
|
3807
3968
|
char buffer[MAX_JSON_INPUT];
|
|
3808
3969
|
|
|
@@ -3818,21 +3979,19 @@ int pjw_call_stop_play_wav(long call_id, const char *json) {
|
|
|
3818
3979
|
goto out;
|
|
3819
3980
|
}
|
|
3820
3981
|
|
|
3821
|
-
res =
|
|
3982
|
+
res = json_get_int_param(document, "media_id", true, &media_id);
|
|
3822
3983
|
if (res <= 0) {
|
|
3823
3984
|
goto out;
|
|
3824
3985
|
}
|
|
3825
3986
|
|
|
3826
3987
|
if (NOT_FOUND_OPTIONAL == res) {
|
|
3827
|
-
// Stop
|
|
3828
|
-
status =
|
|
3829
|
-
if (status != PJ_SUCCESS)
|
|
3830
|
-
goto out;
|
|
3831
|
-
}
|
|
3988
|
+
// Stop op on all audio endpoints
|
|
3989
|
+
status = call_stop_op_on_all_audio_endpoints(call, op);
|
|
3990
|
+
if (status != PJ_SUCCESS) goto out;
|
|
3832
3991
|
} else {
|
|
3833
|
-
// Stop
|
|
3992
|
+
// Stop op on specified media
|
|
3834
3993
|
|
|
3835
|
-
if (
|
|
3994
|
+
if (media_id >= call->media_count) {
|
|
3836
3995
|
set_error("invalid media_id");
|
|
3837
3996
|
goto out;
|
|
3838
3997
|
}
|
|
@@ -3845,10 +4004,8 @@ int pjw_call_stop_play_wav(long call_id, const char *json) {
|
|
|
3845
4004
|
|
|
3846
4005
|
ae = (AudioEndpoint *)me->endpoint.audio;
|
|
3847
4006
|
|
|
3848
|
-
status =
|
|
3849
|
-
if (status != PJ_SUCCESS)
|
|
3850
|
-
goto out;
|
|
3851
|
-
}
|
|
4007
|
+
status = op(call, ae);
|
|
4008
|
+
if (status != PJ_SUCCESS) goto out;
|
|
3852
4009
|
}
|
|
3853
4010
|
|
|
3854
4011
|
out:
|
|
@@ -3860,84 +4017,41 @@ out:
|
|
|
3860
4017
|
return 0;
|
|
3861
4018
|
}
|
|
3862
4019
|
|
|
3863
|
-
pj_status_t
|
|
3864
|
-
return audio_endpoint_remove_port(call, &ae->
|
|
4020
|
+
pj_status_t audio_endpoint_stop_speech_synth(Call *call, AudioEndpoint *ae) {
|
|
4021
|
+
return audio_endpoint_remove_port(call, &ae->flite_cbp);
|
|
3865
4022
|
}
|
|
3866
4023
|
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
long val;
|
|
3872
|
-
Call *call = (Call *)val;
|
|
3873
|
-
pj_status_t status;
|
|
3874
|
-
|
|
3875
|
-
MediaEndpoint *me;
|
|
3876
|
-
AudioEndpoint *ae;
|
|
3877
|
-
int res;
|
|
3878
|
-
|
|
3879
|
-
unsigned media_id = 0;
|
|
3880
|
-
|
|
3881
|
-
char buffer[MAX_JSON_INPUT];
|
|
3882
|
-
|
|
3883
|
-
Document document;
|
|
3884
|
-
|
|
3885
|
-
if (!g_call_ids.get(call_id, val)) {
|
|
3886
|
-
set_error("Invalid call_id");
|
|
3887
|
-
goto out;
|
|
3888
|
-
}
|
|
3889
|
-
call = (Call *)val;
|
|
3890
|
-
|
|
3891
|
-
if (!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
3892
|
-
goto out;
|
|
3893
|
-
}
|
|
3894
|
-
|
|
3895
|
-
res = json_get_uint_param(document, "media_id", true, &media_id);
|
|
3896
|
-
if (res <= 0) {
|
|
3897
|
-
goto out;
|
|
3898
|
-
}
|
|
3899
|
-
|
|
3900
|
-
if (NOT_FOUND_OPTIONAL == res) {
|
|
3901
|
-
// Stop record wav in all audio endpoints
|
|
3902
|
-
status = call_stop_audio_endpoints_op(call, audio_endpoint_stop_record_wav);
|
|
3903
|
-
if (status != PJ_SUCCESS) {
|
|
3904
|
-
goto out;
|
|
3905
|
-
}
|
|
3906
|
-
} else {
|
|
3907
|
-
// Stop record wav on specified media_id
|
|
4024
|
+
pj_status_t audio_endpoint_stop_play_wav(Call *call, AudioEndpoint *ae) {
|
|
4025
|
+
return audio_endpoint_remove_port(call, &ae->wav_player_cbp);
|
|
4026
|
+
}
|
|
3908
4027
|
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
}
|
|
4028
|
+
pj_status_t audio_endpoint_stop_record_wav(Call *call, AudioEndpoint *ae) {
|
|
4029
|
+
return audio_endpoint_remove_port(call, &ae->wav_writer_cbp);
|
|
4030
|
+
}
|
|
3913
4031
|
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
goto out;
|
|
3918
|
-
}
|
|
4032
|
+
pj_status_t audio_endpoint_stop_fax(Call *call, AudioEndpoint *ae) {
|
|
4033
|
+
return audio_endpoint_remove_port(call, &ae->fax_cbp);
|
|
4034
|
+
}
|
|
3919
4035
|
|
|
3920
|
-
ae = (AudioEndpoint *)me->endpoint.audio;
|
|
3921
4036
|
|
|
3922
|
-
status = audio_endpoint_stop_record_wav(call, ae);
|
|
3923
|
-
if (status != PJ_SUCCESS) {
|
|
3924
|
-
goto out;
|
|
3925
|
-
}
|
|
3926
|
-
}
|
|
3927
4037
|
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
return -1;
|
|
3932
|
-
}
|
|
4038
|
+
int pjw_call_stop_speech_synth(long call_id, const char *json) {
|
|
4039
|
+
return audio_endpoint_stop_op(call_id, json, audio_endpoint_stop_speech_synth);
|
|
4040
|
+
}
|
|
3933
4041
|
|
|
3934
|
-
|
|
4042
|
+
int pjw_call_stop_play_wav(long call_id, const char *json) {
|
|
4043
|
+
return audio_endpoint_stop_op(call_id, json, audio_endpoint_stop_play_wav);
|
|
4044
|
+
}
|
|
4045
|
+
|
|
4046
|
+
int pjw_call_stop_record_wav(long call_id, const char *json) {
|
|
4047
|
+
return audio_endpoint_stop_op(call_id, json, audio_endpoint_stop_record_wav);
|
|
3935
4048
|
}
|
|
3936
4049
|
|
|
3937
|
-
|
|
3938
|
-
return
|
|
4050
|
+
int pjw_call_stop_fax(long call_id, const char *json) {
|
|
4051
|
+
return audio_endpoint_stop_op(call_id, json, audio_endpoint_stop_fax);
|
|
3939
4052
|
}
|
|
3940
4053
|
|
|
4054
|
+
|
|
3941
4055
|
int pjw_call_start_fax(long call_id, const char *json) {
|
|
3942
4056
|
PJW_LOCK();
|
|
3943
4057
|
clear_error();
|
|
@@ -3954,8 +4068,9 @@ int pjw_call_start_fax(long call_id, const char *json) {
|
|
|
3954
4068
|
MediaEndpoint *me;
|
|
3955
4069
|
AudioEndpoint *ae;
|
|
3956
4070
|
int ae_count;
|
|
4071
|
+
int res;
|
|
3957
4072
|
|
|
3958
|
-
|
|
4073
|
+
int media_id = -1;
|
|
3959
4074
|
|
|
3960
4075
|
char buffer[MAX_JSON_INPUT];
|
|
3961
4076
|
|
|
@@ -3994,46 +4109,10 @@ int pjw_call_start_fax(long call_id, const char *json) {
|
|
|
3994
4109
|
goto out;
|
|
3995
4110
|
}
|
|
3996
4111
|
|
|
3997
|
-
if (ae_count > 1) {
|
|
3998
|
-
if (json_get_uint_param(document, "media_id", false, &media_id) <= 0) {
|
|
3999
|
-
goto out;
|
|
4000
|
-
}
|
|
4001
|
-
}
|
|
4002
|
-
|
|
4003
|
-
if ((int)media_id >= call->media_count) {
|
|
4004
|
-
set_error("invalid media_id");
|
|
4005
|
-
goto out;
|
|
4006
|
-
}
|
|
4007
|
-
|
|
4008
|
-
me = (MediaEndpoint *)call->media[media_id];
|
|
4009
|
-
if (ENDPOINT_TYPE_AUDIO != me->type) {
|
|
4010
|
-
set_error("media_endpoint is not audio endpoint");
|
|
4011
|
-
goto out;
|
|
4012
|
-
}
|
|
4013
|
-
|
|
4014
|
-
ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4015
|
-
|
|
4016
|
-
if (!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
4017
|
-
goto out;
|
|
4018
|
-
}
|
|
4019
|
-
|
|
4020
|
-
if (!validate_params(document, valid_params)) {
|
|
4021
|
-
goto out;
|
|
4022
|
-
}
|
|
4023
|
-
|
|
4024
4112
|
if (json_get_bool_param(document, "is_sender", false, &is_sender) <= 0) {
|
|
4025
4113
|
goto out;
|
|
4026
4114
|
}
|
|
4027
4115
|
|
|
4028
|
-
if (json_get_string_param(document, "file", false, &file) <= 0) {
|
|
4029
|
-
goto out;
|
|
4030
|
-
}
|
|
4031
|
-
|
|
4032
|
-
if (!file[0]) {
|
|
4033
|
-
set_error("file cannot be blank string");
|
|
4034
|
-
goto out;
|
|
4035
|
-
}
|
|
4036
|
-
|
|
4037
4116
|
flag = false;
|
|
4038
4117
|
if (json_get_bool_param(document, "transmit_on_idle", true, &flag) <= 0) {
|
|
4039
4118
|
goto out;
|
|
@@ -4042,73 +4121,50 @@ int pjw_call_start_fax(long call_id, const char *json) {
|
|
|
4042
4121
|
flags |= FAX_FLAG_TRANSMIT_ON_IDLE;
|
|
4043
4122
|
}
|
|
4044
4123
|
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
int pjw_call_stop_fax(long call_id, const char *json) {
|
|
4067
|
-
PJW_LOCK();
|
|
4068
|
-
clear_error();
|
|
4069
|
-
|
|
4070
|
-
long val;
|
|
4071
|
-
Call *call;
|
|
4072
|
-
|
|
4073
|
-
pj_status_t status;
|
|
4074
|
-
|
|
4075
|
-
MediaEndpoint *me;
|
|
4076
|
-
AudioEndpoint *ae;
|
|
4077
|
-
int res;
|
|
4078
|
-
|
|
4079
|
-
unsigned media_id = 0;
|
|
4080
|
-
|
|
4081
|
-
char buffer[MAX_JSON_INPUT];
|
|
4082
|
-
|
|
4083
|
-
Document document;
|
|
4084
|
-
|
|
4085
|
-
if (!g_call_ids.get(call_id, val)) {
|
|
4086
|
-
set_error("Invalid call_id");
|
|
4087
|
-
goto out;
|
|
4088
|
-
}
|
|
4089
|
-
call = (Call *)val;
|
|
4124
|
+
if(is_sender) {
|
|
4125
|
+
// if we are sender we can do fax operaton to all media streams
|
|
4126
|
+
res = json_get_int_param(document, "media_id", true, &media_id);
|
|
4127
|
+
if (res <= 0) goto out;
|
|
4128
|
+
|
|
4129
|
+
if (NOT_FOUND_OPTIONAL == res) {
|
|
4130
|
+
// start fax on all audio endpoints
|
|
4131
|
+
for (int i = 0; i < call->media_count; i++) {
|
|
4132
|
+
MediaEndpoint *me = (MediaEndpoint *)call->media[i];
|
|
4133
|
+
if (ENDPOINT_TYPE_AUDIO == me->type) {
|
|
4134
|
+
me = (MediaEndpoint *)call->media[i];
|
|
4135
|
+
ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4136
|
+
status = audio_endpoint_start_fax(call, ae, is_sender, file, flags);
|
|
4137
|
+
if(status != PJ_SUCCESS) goto out;
|
|
4138
|
+
}
|
|
4139
|
+
}
|
|
4140
|
+
} else {
|
|
4141
|
+
if ((int)media_id >= call->media_count) {
|
|
4142
|
+
set_error("invalid media_id");
|
|
4143
|
+
goto out;
|
|
4144
|
+
}
|
|
4090
4145
|
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4146
|
+
me = (MediaEndpoint *)call->media[media_id];
|
|
4147
|
+
if (ENDPOINT_TYPE_AUDIO != me->type) {
|
|
4148
|
+
set_error("invalid media_id non audio");
|
|
4149
|
+
goto out;
|
|
4150
|
+
}
|
|
4094
4151
|
|
|
4095
|
-
|
|
4096
|
-
if (res <= 0) {
|
|
4097
|
-
goto out;
|
|
4098
|
-
}
|
|
4152
|
+
ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4099
4153
|
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
status = call_stop_audio_endpoints_op(call, audio_endpoint_stop_fax);
|
|
4103
|
-
if (status != PJ_SUCCESS) {
|
|
4104
|
-
goto out;
|
|
4154
|
+
status = audio_endpoint_start_fax(call, ae, is_sender, file, flags);
|
|
4155
|
+
if (status != PJ_SUCCESS) goto out;
|
|
4105
4156
|
}
|
|
4106
4157
|
} else {
|
|
4107
|
-
//
|
|
4108
|
-
|
|
4109
|
-
if (
|
|
4110
|
-
|
|
4111
|
-
|
|
4158
|
+
// if we are not sender we can only start fax operation in a single media endpoint (otherwise, there would be more than one fax process writing to the same fax file)
|
|
4159
|
+
res = json_get_int_param(document, "media_id", true, &media_id);
|
|
4160
|
+
if (res <= 0) goto out;
|
|
4161
|
+
|
|
4162
|
+
if (NOT_FOUND_OPTIONAL == res) {
|
|
4163
|
+
media_id = get_first_media_id_by_type(call, ENDPOINT_TYPE_AUDIO);
|
|
4164
|
+
if(media_id < 0) {
|
|
4165
|
+
set_error("could not resolve media_id");
|
|
4166
|
+
goto out;
|
|
4167
|
+
}
|
|
4112
4168
|
}
|
|
4113
4169
|
|
|
4114
4170
|
me = (MediaEndpoint *)call->media[media_id];
|
|
@@ -4119,10 +4175,11 @@ int pjw_call_stop_fax(long call_id, const char *json) {
|
|
|
4119
4175
|
|
|
4120
4176
|
ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4121
4177
|
|
|
4178
|
+
// First stop and destroy existing fax port.
|
|
4122
4179
|
status = audio_endpoint_stop_fax(call, ae);
|
|
4123
|
-
if
|
|
4124
|
-
|
|
4125
|
-
|
|
4180
|
+
if(status != PJ_SUCCESS) goto out;
|
|
4181
|
+
|
|
4182
|
+
if (!prepare_fax(call, ae, is_sender, file, flags)) goto out;
|
|
4126
4183
|
}
|
|
4127
4184
|
|
|
4128
4185
|
out:
|
|
@@ -4889,6 +4946,7 @@ static void on_state_changed(pjsip_inv_session *inv, pjsip_event *e) {
|
|
|
4889
4946
|
sip_msg = e->body.rx_msg.rdata->msg_info.msg_buf;
|
|
4890
4947
|
}
|
|
4891
4948
|
|
|
4949
|
+
printf("call_id=%li sip_msg_len=%i sip_msg=%p\n", call_id, sip_msg_len, sip_msg);
|
|
4892
4950
|
make_evt_call_ended(evt, sizeof(evt), call_id, sip_msg_len, sip_msg);
|
|
4893
4951
|
dispatch_event(evt);
|
|
4894
4952
|
}
|
|
@@ -6475,6 +6533,7 @@ void close_media_endpoint(Call *call, MediaEndpoint *me) {
|
|
|
6475
6533
|
audio_endpoint_remove_port(call, &ae->tonegen_cbp);
|
|
6476
6534
|
audio_endpoint_remove_port(call, &ae->dtmfdet_cbp);
|
|
6477
6535
|
audio_endpoint_remove_port(call, &ae->fax_cbp);
|
|
6536
|
+
audio_endpoint_remove_port(call, &ae->flite_cbp);
|
|
6478
6537
|
|
|
6479
6538
|
close_media_transport(ae->med_transport);
|
|
6480
6539
|
ae->med_transport = NULL;
|
|
@@ -6500,7 +6559,7 @@ void close_media_endpoint(Call *call, MediaEndpoint *me) {
|
|
|
6500
6559
|
}
|
|
6501
6560
|
|
|
6502
6561
|
void close_media(Call *c) {
|
|
6503
|
-
printf("close_media call_id=%
|
|
6562
|
+
printf("close_media call_id=%i\n", c->id);
|
|
6504
6563
|
for (int i = 0; i < c->media_count; ++i) {
|
|
6505
6564
|
MediaEndpoint *me = c->media[i];
|
|
6506
6565
|
close_media_endpoint(c, me);
|
|
@@ -6542,7 +6601,7 @@ bool prepare_tonegen(Call *c, AudioEndpoint *ae) {
|
|
|
6542
6601
|
return true;
|
|
6543
6602
|
}
|
|
6544
6603
|
|
|
6545
|
-
bool prepare_wav_player(Call *c, AudioEndpoint *ae, const char *file) {
|
|
6604
|
+
bool prepare_wav_player(Call *c, AudioEndpoint *ae, const char *file, unsigned flags, bool end_of_file_event) {
|
|
6546
6605
|
pj_status_t status;
|
|
6547
6606
|
|
|
6548
6607
|
unsigned wav_ptime;
|
|
@@ -6553,7 +6612,7 @@ bool prepare_wav_player(Call *c, AudioEndpoint *ae, const char *file) {
|
|
|
6553
6612
|
c->inv->pool,
|
|
6554
6613
|
file,
|
|
6555
6614
|
wav_ptime,
|
|
6556
|
-
|
|
6615
|
+
flags,
|
|
6557
6616
|
-1, /* buf size */
|
|
6558
6617
|
&ae->wav_player_cbp.port
|
|
6559
6618
|
);
|
|
@@ -6563,6 +6622,14 @@ bool prepare_wav_player(Call *c, AudioEndpoint *ae, const char *file) {
|
|
|
6563
6622
|
return false;
|
|
6564
6623
|
}
|
|
6565
6624
|
|
|
6625
|
+
if (end_of_file_event) {
|
|
6626
|
+
status = pjmedia_wav_player_set_eof_cb2(ae->wav_player_cbp.port, (void*)c, on_end_of_file);
|
|
6627
|
+
if (status != PJ_SUCCESS) {
|
|
6628
|
+
set_error("pjmedia_wav_player_set_eof_cb2 failed");
|
|
6629
|
+
return false;
|
|
6630
|
+
}
|
|
6631
|
+
}
|
|
6632
|
+
|
|
6566
6633
|
status = pjmedia_conf_add_port(c->conf, c->inv->pool, ae->wav_player_cbp.port, NULL, &ae->wav_player_cbp.slot);
|
|
6567
6634
|
if (status != PJ_SUCCESS) {
|
|
6568
6635
|
set_error("pjmedia_conf_add_port failed");
|
|
@@ -6672,7 +6739,7 @@ bool prepare_fax(Call *c, AudioEndpoint *ae, bool is_sender, const char *file,
|
|
|
6672
6739
|
return true;
|
|
6673
6740
|
}
|
|
6674
6741
|
|
|
6675
|
-
bool prepare_flite(Call *c, AudioEndpoint *ae, const char *voice) {
|
|
6742
|
+
bool prepare_flite(Call *c, AudioEndpoint *ae, const char *voice, bool end_of_speech_event) {
|
|
6676
6743
|
printf("prepare_flite call.id=%i\n", c->id);
|
|
6677
6744
|
pj_status_t status;
|
|
6678
6745
|
|
|
@@ -6685,12 +6752,20 @@ bool prepare_flite(Call *c, AudioEndpoint *ae, const char *voice) {
|
|
|
6685
6752
|
c->inv->pool, PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
6686
6753
|
PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info),
|
|
6687
6754
|
PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
|
|
6688
|
-
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
|
|
6755
|
+
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info), voice, &ae->flite_cbp.port);
|
|
6689
6756
|
if (status != PJ_SUCCESS) {
|
|
6690
6757
|
set_error("pjmedia_flite_port_create failed");
|
|
6691
6758
|
return false;
|
|
6692
6759
|
}
|
|
6693
6760
|
|
|
6761
|
+
if (end_of_speech_event) {
|
|
6762
|
+
status = pjmedia_flite_port_set_eof_cb(ae->flite_cbp.port, (void*)c, on_end_of_speech);
|
|
6763
|
+
if (status != PJ_SUCCESS) {
|
|
6764
|
+
set_error("pjmedia_flite_port_set_eof_cb failed");
|
|
6765
|
+
return false;
|
|
6766
|
+
}
|
|
6767
|
+
}
|
|
6768
|
+
|
|
6694
6769
|
status = pjmedia_conf_add_port(c->conf, c->inv->pool, ae->flite_cbp.port, NULL, &ae->flite_cbp.slot);
|
|
6695
6770
|
if (status != PJ_SUCCESS) {
|
|
6696
6771
|
set_error("pjmedia_conf_add_port failed");
|
|
@@ -8012,7 +8087,7 @@ int pjw_call_send_tcp_msg(long call_id, const char *json) {
|
|
|
8012
8087
|
MediaEndpoint *me;
|
|
8013
8088
|
int res;
|
|
8014
8089
|
|
|
8015
|
-
|
|
8090
|
+
int media_id = -1;
|
|
8016
8091
|
|
|
8017
8092
|
char buffer[MAX_JSON_INPUT];
|
|
8018
8093
|
|
|
@@ -8036,7 +8111,7 @@ int pjw_call_send_tcp_msg(long call_id, const char *json) {
|
|
|
8036
8111
|
}
|
|
8037
8112
|
size = strlen(msg);
|
|
8038
8113
|
|
|
8039
|
-
res =
|
|
8114
|
+
res = json_get_int_param(document, "media_id", true, &media_id);
|
|
8040
8115
|
if (res <= 0) {
|
|
8041
8116
|
goto out;
|
|
8042
8117
|
}
|
|
@@ -8050,7 +8125,7 @@ int pjw_call_send_tcp_msg(long call_id, const char *json) {
|
|
|
8050
8125
|
} else {
|
|
8051
8126
|
// Send msg to specified media_id
|
|
8052
8127
|
|
|
8053
|
-
if (
|
|
8128
|
+
if (media_id >= call->media_count) {
|
|
8054
8129
|
set_error("invalid media_id");
|
|
8055
8130
|
goto out;
|
|
8056
8131
|
}
|