From ea5c38528151a3a8d770708223241da3adab64a1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 9 Jan 2009 20:34:01 +0000 Subject: [PATCH] numerous fixes from regression testing git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11104 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_core.h | 4 +- src/include/switch_module_interfaces.h | 3 + src/include/switch_types.h | 8 +- .../mod_conference/mod_conference.c | 359 +++++++++++------- src/mod/applications/mod_rss/mod_rss.c | 2 +- src/mod/endpoints/mod_loopback/mod_loopback.c | 5 +- src/mod/endpoints/mod_sofia/sofia_glue.c | 2 +- .../mod_erlang_event/mod_erlang_event.c | 4 +- .../mod_event_socket/mod_event_socket.c | 4 +- .../mod_local_stream/mod_local_stream.c | 1 + src/switch_core.c | 5 +- src/switch_core_file.c | 89 ++++- src/switch_core_io.c | 8 +- src/switch_core_session.c | 25 +- src/switch_core_state_machine.c | 2 +- src/switch_ivr.c | 2 +- src/switch_ivr_async.c | 13 +- src/switch_ivr_bridge.c | 6 +- src/switch_ivr_originate.c | 24 +- src/switch_ivr_play_say.c | 30 +- 20 files changed, 401 insertions(+), 195 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 0abeb67764..f36c067a85 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -330,7 +330,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_perform_read_lock_hangup(_In \return success if it is safe to read from the session */ #ifdef SWITCH_DEBUG_RWLOCKS -#define switch_core_session_read_lock(session) switch_core_session_perform_read_lock_hangup(session, __FILE__, __SWITCH_FUNC__, __LINE__) +#define switch_core_session_read_lock_hangup(session) switch_core_session_perform_read_lock_hangup(session, __FILE__, __SWITCH_FUNC__, __LINE__) #else SWITCH_DECLARE(switch_status_t) switch_core_session_read_lock_hangup(_In_ switch_core_session_t *session); #endif @@ -901,7 +901,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(_In_ switc \param session the session to reset \param flush_dtmf flush all queued dtmf events too */ -SWITCH_DECLARE(void) switch_core_session_reset(_In_ switch_core_session_t *session, switch_bool_t flush_dtmf); +SWITCH_DECLARE(void) switch_core_session_reset(_In_ switch_core_session_t *session, switch_bool_t flush_dtmf, switch_bool_t reset_read_codec); /*! \brief Write a frame to a session diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 238825d328..cee2cfbf4d 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -320,6 +320,9 @@ struct switch_file_handle { switch_buffer_t *buffer; switch_byte_t *dbuf; switch_size_t dbuflen; + switch_buffer_t *pre_buffer; + unsigned char *pre_buffer_data; + switch_size_t pre_buffer_datalen; const char *file; const char *func; int line; diff --git a/src/include/switch_types.h b/src/include/switch_types.h index b28914cc40..533927bdd4 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -166,7 +166,9 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_SPEECH_KEY "speech" #define SWITCH_UUID_BRIDGE "uuid_bridge" #define SWITCH_BITS_PER_BYTE 8 - typedef uint8_t switch_byte_t; +#define SWITCH_DEFAULT_FILE_BUFFER_LEN 65536 + +typedef uint8_t switch_byte_t; typedef struct { char digit; @@ -1061,7 +1063,9 @@ typedef enum { SWITCH_FILE_NATIVE = (1 << 9), SWITCH_FILE_SEEK = (1 << 10), SWITCH_FILE_OPEN = (1 << 11), - SWITCH_FILE_CALLBACK = (1 << 12) + SWITCH_FILE_CALLBACK = (1 << 12), + SWITCH_FILE_DONE = (1 << 13), + SWITCH_FILE_BUFFER_DONE = (1 << 14) } switch_file_flag_enum_t; typedef uint32_t switch_file_flag_t; diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index c7ba129aa7..6dc0499238 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -1,4 +1,4 @@ -/* +/* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * Copyright (C) 2005/2006, Anthony Minessale II * @@ -139,7 +139,8 @@ typedef enum { MFLAG_FLUSH_BUFFER = (1 << 8), MFLAG_ENDCONF = (1 << 9), MFLAG_HAS_AUDIO = (1 << 10), - MFLAG_TALKING = (1 << 11) + MFLAG_TALKING = (1 << 11), + MFLAG_RESTART = (1 << 12) } member_flag_t; typedef enum { @@ -337,6 +338,7 @@ typedef struct api_command { } api_command_t; /* Function Prototypes */ +static int setup_media(conference_member_t *member, conference_obj_t *conference); static uint32_t next_member_id(void); static conference_relationship_t *member_get_relationship(conference_member_t *member, conference_member_t *other_member); static conference_member_t *conference_member_get(conference_obj_t *conference, uint32_t id); @@ -1758,18 +1760,43 @@ static caller_control_fn_table_t ccfntbl[] = { /* NB. this starts the input thread after some initial setup for the call leg */ static void conference_loop_output(conference_member_t *member) { - switch_channel_t *channel = switch_core_session_get_channel(member->session); + switch_channel_t *channel; switch_frame_t write_frame = { 0 }; - uint8_t *data; + uint8_t *data = NULL; switch_timer_t timer = { 0 }; - switch_codec_t *read_codec = switch_core_session_get_read_codec(member->session); - uint32_t interval = read_codec->implementation->microseconds_per_packet / 1000; - uint32_t samples = switch_samples_per_packet(member->conference->rate, interval); - uint32_t csamples = samples; - uint32_t tsamples = member->orig_read_codec->implementation->samples_per_packet; - uint32_t flush_len = 0; - uint32_t low_count = 0, bytes = samples * 2; - call_list_t *call_list = NULL, *cp = NULL; + switch_codec_t *read_codec; + uint32_t interval; + uint32_t samples; + uint32_t csamples; + uint32_t tsamples; + uint32_t flush_len; + uint32_t low_count, bytes; + call_list_t *call_list, *cp; + int restarting = -1; + + top: + + restarting++; + + if (switch_test_flag(member, MFLAG_RESTART)) { + switch_clear_flag(member, MFLAG_RESTART); + switch_set_flag_locked(member, MFLAG_FLUSH_BUFFER); + switch_core_timer_destroy(&timer); + } + + channel = switch_core_session_get_channel(member->session); + read_codec = switch_core_session_get_read_codec(member->session); + interval = read_codec->implementation->microseconds_per_packet / 1000; + samples = switch_samples_per_packet(member->conference->rate, interval); + csamples = samples; + tsamples = member->orig_read_codec->implementation->samples_per_packet; + flush_len = 0; + low_count = 0; + bytes = samples * 2; + call_list = NULL; + cp = NULL; + + switch_assert(member->conference != NULL); @@ -1783,62 +1810,72 @@ static void conference_loop_output(conference_member_t *member) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Setup timer %s success interval: %u samples: %u\n", member->conference->timer_name, interval, tsamples); - write_frame.data = data = switch_core_session_alloc(member->session, SWITCH_RECOMMENDED_BUFFER_SIZE); - write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; + if (!restarting) { + write_frame.data = data = switch_core_session_alloc(member->session, SWITCH_RECOMMENDED_BUFFER_SIZE); + write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; + } + write_frame.codec = &member->write_codec; if (!switch_test_flag(member->conference, CFLAG_ANSWERED)) { switch_channel_answer(channel); } - /* Start the input thread */ - launch_conference_loop_input(member, switch_core_session_get_pool(member->session)); - - /* build a digit stream object */ - if (member->conference->dtmf_parser != NULL - && switch_ivr_digit_stream_new(member->conference->dtmf_parser, &member->digit_stream) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Danger Will Robinson, there is no digit parser stream object\n"); - } - - if ((call_list = switch_channel_get_private(channel, "_conference_autocall_list_"))) { - const char *cid_name = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_name"); - const char *cid_num = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_number"); - const char *toval = switch_channel_get_variable(channel, "conference_auto_outcall_timeout"); - const char *flags = switch_channel_get_variable(channel, "conference_auto_outcall_flags"); - const char *ann = switch_channel_get_variable(channel, "conference_auto_outcall_announce"); - const char *prefix = switch_channel_get_variable(channel, "conference_auto_outcall_prefix"); - int to = 60; + if (!restarting) { + /* Start the input thread */ + launch_conference_loop_input(member, switch_core_session_get_pool(member->session)); - if (ann) { - member->conference->special_announce = switch_core_strdup(member->conference->pool, ann); + /* build a digit stream object */ + if (member->conference->dtmf_parser != NULL + && switch_ivr_digit_stream_new(member->conference->dtmf_parser, &member->digit_stream) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Danger Will Robinson, there is no digit parser stream object\n"); } - switch_channel_set_private(channel, "_conference_autocall_list_", NULL); - - if (toval) { - to = atoi(toval); - if (to < 10 || to > 500) { - to = 60; + if ((call_list = switch_channel_get_private(channel, "_conference_autocall_list_"))) { + const char *cid_name = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_name"); + const char *cid_num = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_number"); + const char *toval = switch_channel_get_variable(channel, "conference_auto_outcall_timeout"); + const char *flags = switch_channel_get_variable(channel, "conference_auto_outcall_flags"); + const char *ann = switch_channel_get_variable(channel, "conference_auto_outcall_announce"); + const char *prefix = switch_channel_get_variable(channel, "conference_auto_outcall_prefix"); + int to = 60; + + if (ann) { + member->conference->special_announce = switch_core_strdup(member->conference->pool, ann); } - } - for (cp = call_list; cp; cp = cp->next) { - int argc; - char *argv[512] = { 0 }; - char *cpstr = strdup(cp->string); - int x = 0; + switch_channel_set_private(channel, "_conference_autocall_list_", NULL); - switch_assert(cpstr); - argc = switch_separate_string(cpstr, ',', argv, (sizeof(argv) / sizeof(argv[0]))); - for (x = 0; x < argc; x++) { - char *dial_str = switch_mprintf("%s%s", switch_str_nil(prefix), argv[x]); - switch_assert(dial_str); - conference_outcall_bg(member->conference, NULL, NULL, dial_str, to, switch_str_nil(flags), cid_name, cid_num); - switch_safe_free(dial_str); + if (toval) { + to = atoi(toval); + if (to < 10 || to > 500) { + to = 60; + } + } + + for (cp = call_list; cp; cp = cp->next) { + int argc; + char *argv[512] = { 0 }; + char *cpstr = strdup(cp->string); + int x = 0; + + switch_assert(cpstr); + argc = switch_separate_string(cpstr, ',', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { + char *dial_str = switch_mprintf("%s%s", switch_str_nil(prefix), argv[x]); + switch_assert(dial_str); + conference_outcall_bg(member->conference, NULL, NULL, dial_str, to, switch_str_nil(flags), cid_name, cid_num); + switch_safe_free(dial_str); + } + switch_safe_free(cpstr); } - switch_safe_free(cpstr); } } + + if (restarting) { + switch_channel_clear_flag(channel, CF_SERVICE); + } + /* Fair WARNING, If you expect the caller to hear anything or for digit handling to be processed, */ /* you better not block this thread loop for more than the duration of member->conference->timer_name! */ while (switch_test_flag(member, MFLAG_RUNNING) && switch_test_flag(member, MFLAG_ITHREAD) @@ -1852,6 +1889,10 @@ static void conference_loop_output(conference_member_t *member) switch_size_t file_sample_len = csamples; switch_size_t file_data_len = file_sample_len * 2; + if (switch_test_flag(member, MFLAG_RESTART)) { + goto top; + } + switch_mutex_lock(member->flag_mutex); if (switch_core_session_dequeue_event(member->session, &event) == SWITCH_STATUS_SUCCESS) { @@ -2145,6 +2186,8 @@ static void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *th switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Joining Conference\n"); goto end; } + + fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN; if (switch_core_file_open(&fh, rec->path, (uint8_t) 1, conference->rate, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, @@ -2371,6 +2414,7 @@ static switch_status_t conference_play_file(conference_obj_t *conference, char * fnode->leadin = leadin; /* Open the file */ + fnode->fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN; if (switch_core_file_open(&fnode->fh, file, (uint8_t) 1, conference->rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, pool) != SWITCH_STATUS_SUCCESS) { switch_core_destroy_memory_pool(&pool); @@ -2465,6 +2509,7 @@ static switch_status_t conference_member_play_file(conference_member_t *member, fnode->type = NODE_TYPE_FILE; fnode->leadin = leadin; /* Open the file */ + fnode->fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN; if (switch_core_file_open(&fnode->fh, file, (uint8_t) 1, member->conference->rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, pool) != SWITCH_STATUS_SUCCESS) { @@ -3631,9 +3676,21 @@ static switch_status_t conf_api_sub_transfer(conference_obj_t *conference, switc switch_mutex_lock(member->flag_mutex); conference_del_member(conference, member); conference_add_member(new_conference, member); + + if (conference->rate != new_conference->rate) { + if(setup_media(member, new_conference)) { + switch_clear_flag_locked(member, MFLAG_RUNNING); + } else { + switch_channel_set_flag(channel, CF_SERVICE); + switch_set_flag(member, MFLAG_RESTART); + } + } + switch_mutex_unlock(new_conference->mutex); switch_mutex_unlock(member->flag_mutex); - stream->write_function(stream, "OK Members sent to conference %s.\n", argv[2]); + + + stream->write_function(stream, "OK Member '%d' sent to conference %s.\n", member->id, argv[2]); /* tell them what happened */ if (test_eflag(conference, EFLAG_TRANSFER) && @@ -4349,6 +4406,111 @@ SWITCH_STANDARD_APP(conference_auto_function) switch_channel_set_private(channel, "_conference_autocall_list_", call_list); } + +static int setup_media(conference_member_t *member, conference_obj_t *conference) +{ + switch_codec_t *read_codec; + + + switch_core_session_reset(member->session, SWITCH_TRUE, SWITCH_FALSE); + + if (member->read_codec.implementation) { + switch_core_codec_destroy(&member->read_codec); + } + + if (member->read_resampler) { + switch_resample_destroy(&member->read_resampler); + } + + read_codec = switch_core_session_get_read_codec(member->session); + member->orig_read_codec = read_codec; + member->native_rate = read_codec->implementation->samples_per_second; + + /* Setup a Signed Linear codec for reading audio. */ + if (switch_core_codec_init(&member->read_codec, + "L16", + NULL, read_codec->implementation->actual_samples_per_second, read_codec->implementation->microseconds_per_packet / 1000, + 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, member->pool) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, + "Raw Codec Activation Success L16@%uhz 1 channel %dms\n", + read_codec->implementation->actual_samples_per_second, read_codec->implementation->microseconds_per_packet / 1000); + + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz 1 channel %dms\n", + read_codec->implementation->actual_samples_per_second, read_codec->implementation->microseconds_per_packet / 1000); + + goto done; + } + + if (!member->frame_size) { + member->frame_size = SWITCH_RECOMMENDED_BUFFER_SIZE; + member->frame = switch_core_alloc(member->pool, member->frame_size); + member->mux_frame = switch_core_alloc(member->pool, member->frame_size); + } + + if (read_codec->implementation->actual_samples_per_second != conference->rate) { + if (switch_resample_create(&member->read_resampler, + read_codec->implementation->actual_samples_per_second, + member->frame_size, conference->rate, member->frame_size, member->pool) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to create resampler!\n"); + goto done; + } + + + member->resample_out = switch_core_alloc(member->pool, member->frame_size); + member->resample_out_len = member->frame_size; + + /* Setup an audio buffer for the resampled audio */ + if (switch_buffer_create_dynamic(&member->resample_buffer, CONF_DBLOCK_SIZE, CONF_DBUFFER_SIZE, CONF_DBUFFER_MAX) + != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n"); + goto done; + } + } + + + /* Setup a Signed Linear codec for writing audio. */ + if (switch_core_codec_init(&member->write_codec, + "L16", + NULL, + conference->rate, + read_codec->implementation->microseconds_per_packet / 1000, + 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, member->pool) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, + "Raw Codec Activation Success L16@%uhz 1 channel %dms\n", + conference->rate, read_codec->implementation->microseconds_per_packet / 1000); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz 1 channel %dms\n", + conference->rate, read_codec->implementation->microseconds_per_packet / 1000); + goto codec_done2; + } + + /* Setup an audio buffer for the incoming audio */ + if (switch_buffer_create_dynamic(&member->audio_buffer, CONF_DBLOCK_SIZE, CONF_DBUFFER_SIZE, CONF_DBUFFER_MAX) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n"); + goto codec_done1; + } + + /* Setup an audio buffer for the outgoing audio */ + if (switch_buffer_create_dynamic(&member->mux_buffer, CONF_DBLOCK_SIZE, CONF_DBUFFER_SIZE, CONF_DBUFFER_MAX) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n"); + goto codec_done1; + } + + return 0; + + codec_done1: + switch_core_codec_destroy(&member->read_codec); + codec_done2: + switch_core_codec_destroy(&member->write_codec); + done: + + return -1; + + +} + + /* Application interface function that is called from the dialplan to join the channel to a conference */ SWITCH_STANDARD_APP(conference_function) { @@ -4632,84 +4794,16 @@ SWITCH_STANDARD_APP(conference_function) switch_set_flag(conference, CFLAG_ANSWERED); } - member.orig_read_codec = read_codec; - member.native_rate = read_codec->implementation->samples_per_second; + member.session = session; member.pool = switch_core_session_get_pool(session); - /* Setup a Signed Linear codec for reading audio. */ - if (switch_core_codec_init(&member.read_codec, - "L16", - NULL, read_codec->implementation->actual_samples_per_second, read_codec->implementation->microseconds_per_packet / 1000, - 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, member.pool) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "Raw Codec Activation Success L16@%uhz 1 channel %dms\n", - read_codec->implementation->actual_samples_per_second, read_codec->implementation->microseconds_per_packet / 1000); - - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz 1 channel %dms\n", - read_codec->implementation->actual_samples_per_second, read_codec->implementation->microseconds_per_packet / 1000); - + if (setup_media(&member, conference)) { flags = 0; goto done; } - member.frame_size = SWITCH_RECOMMENDED_BUFFER_SIZE; - member.frame = switch_core_alloc(member.pool, member.frame_size); - member.mux_frame = switch_core_alloc(member.pool, member.frame_size); - - if (read_codec->implementation->actual_samples_per_second != conference->rate) { - if (switch_resample_create(&member.read_resampler, - read_codec->implementation->actual_samples_per_second, - member.frame_size, conference->rate, member.frame_size, member.pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to create resampler!\n"); - goto done; - } - - - member.resample_out = switch_core_alloc(member.pool, member.frame_size); - member.resample_out_len = member.frame_size; - - /* Setup an audio buffer for the resampled audio */ - if (switch_buffer_create_dynamic(&member.resample_buffer, CONF_DBLOCK_SIZE, CONF_DBUFFER_SIZE, CONF_DBUFFER_MAX) - != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n"); - goto done; - } - } - - - /* Setup a Signed Linear codec for writing audio. */ - if (switch_core_codec_init(&member.write_codec, - "L16", - NULL, - conference->rate, - read_codec->implementation->microseconds_per_packet / 1000, - 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, member.pool) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "Raw Codec Activation Success L16@%uhz 1 channel %dms\n", - conference->rate, read_codec->implementation->microseconds_per_packet / 1000); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz 1 channel %dms\n", - conference->rate, read_codec->implementation->microseconds_per_packet / 1000); - flags = 0; - goto codec_done2; - } - - /* Setup an audio buffer for the incoming audio */ - if (switch_buffer_create_dynamic(&member.audio_buffer, CONF_DBLOCK_SIZE, CONF_DBUFFER_SIZE, CONF_DBUFFER_MAX) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n"); - goto codec_done1; - } - - /* Setup an audio buffer for the outgoing audio */ - if (switch_buffer_create_dynamic(&member.mux_buffer, CONF_DBLOCK_SIZE, CONF_DBUFFER_SIZE, CONF_DBUFFER_MAX) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n"); - goto codec_done1; - } - /* Prepare MUTEXS */ member.id = next_member_id(); - member.session = session; switch_mutex_init(&member.flag_mutex, SWITCH_MUTEX_NESTED, member.pool); switch_mutex_init(&member.audio_in_mutex, SWITCH_MUTEX_NESTED, member.pool); switch_mutex_init(&member.audio_out_mutex, SWITCH_MUTEX_NESTED, member.pool); @@ -4724,7 +4818,8 @@ SWITCH_STANDARD_APP(conference_function) /* Add the caller to the conference */ if (conference_add_member(conference, &member) != SWITCH_STATUS_SUCCESS) { - goto codec_done1; + switch_core_codec_destroy(&member.read_codec); + goto done; } msg.from = __FILE__; @@ -4747,12 +4842,14 @@ SWITCH_STANDARD_APP(conference_function) /* Put the original codec back */ switch_core_session_set_read_codec(member.session, NULL); - /* Clean Up. codec_done(X): is for error situations after the codecs were setup and done: is for situations before */ - codec_done1: - switch_core_codec_destroy(&member.read_codec); - codec_done2: - switch_core_codec_destroy(&member.write_codec); + /* Clean Up. */ + done: + + if (member.read_resampler) { + switch_resample_destroy(&member.read_resampler); + } + switch_event_destroy(¶ms); switch_buffer_destroy(&member.resample_buffer); switch_buffer_destroy(&member.audio_buffer); @@ -4796,7 +4893,7 @@ SWITCH_STANDARD_APP(conference_function) } } - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); /* release the readlock */ if (rl) { diff --git a/src/mod/applications/mod_rss/mod_rss.c b/src/mod/applications/mod_rss/mod_rss.c index 453f5a71c7..ff55d98efa 100644 --- a/src/mod/applications/mod_rss/mod_rss.c +++ b/src/mod/applications/mod_rss/mod_rss.c @@ -619,7 +619,7 @@ SWITCH_STANDARD_APP(rss_function) } switch_xml_free(xml); - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); } diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index e0e7524ca2..940f014ec8 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -264,7 +264,10 @@ static switch_status_t channel_on_init(switch_core_session_t *session) } if (tech_pvt->other_session) { - switch_core_session_read_lock(tech_pvt->other_session); + if (switch_core_session_read_lock(tech_pvt->other_session) != SWITCH_STATUS_SUCCESS) { + switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + goto end; + } } else { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); goto end; diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 5b338eec61..aa5a656680 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -1623,7 +1623,7 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force) resetting = 1; switch_core_codec_destroy(&tech_pvt->read_codec); switch_core_codec_destroy(&tech_pvt->write_codec); - switch_core_session_reset(tech_pvt->session, SWITCH_TRUE); + switch_core_session_reset(tech_pvt->session, SWITCH_TRUE, SWITCH_TRUE); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Already using %s\n", tech_pvt->read_codec.implementation->iananame); switch_goto_status(SWITCH_STATUS_SUCCESS, end); diff --git a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c index d3e9bbabe4..ef6e26c0ec 100644 --- a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c +++ b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c @@ -1202,7 +1202,9 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj) if ((session = listener->session)) { channel = switch_core_session_get_channel(session); - switch_core_session_read_lock(session); + if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { + goto done; + } } if (switch_strlen_zero(listener->remote_ip)) { diff --git a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c index 25f1b30f8b..cb9da8ba68 100644 --- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c +++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c @@ -1770,7 +1770,9 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj) if ((session = listener->session)) { channel = switch_core_session_get_channel(session); - switch_core_session_read_lock(session); + if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { + goto done; + } } if (prefs.acl_count && listener->sa && !switch_strlen_zero(listener->remote_ip)) { diff --git a/src/mod/formats/mod_local_stream/mod_local_stream.c b/src/mod/formats/mod_local_stream/mod_local_stream.c index ce6f94a636..adad6e5f39 100644 --- a/src/mod/formats/mod_local_stream/mod_local_stream.c +++ b/src/mod/formats/mod_local_stream/mod_local_stream.c @@ -183,6 +183,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void fname = path_buf; fh.prebuf = source->prebuf; + fh.pre_buffer_datalen = 65536; if (switch_core_file_open(&fh, (char *) fname, diff --git a/src/switch_core.c b/src/switch_core.c index d910d8e93d..2926a42a88 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -277,7 +277,10 @@ static void *switch_core_service_thread(switch_thread_t *thread, void *obj) switch_assert(thread != NULL); switch_assert(session != NULL); - switch_core_session_read_lock(session); + if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { + return NULL; + } + channel = switch_core_session_get_channel(session); switch_channel_set_flag(channel, CF_SERVICE); diff --git a/src/switch_core_file.c b/src/switch_core_file.c index cc3166133b..2914ffedc8 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -117,6 +117,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, } } + if (fh->pre_buffer_datalen) { + //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Prebuffering %d bytes\n", (int)fh->pre_buffer_datalen); + switch_buffer_create_dynamic(&fh->pre_buffer, fh->pre_buffer_datalen, fh->pre_buffer_datalen / 2, 0); + fh->pre_buffer_data = switch_core_alloc(fh->memory_pool, fh->pre_buffer_datalen); + } + switch_set_flag(fh, SWITCH_FILE_OPEN); return status; @@ -124,26 +130,61 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh, void *data, switch_size_t *len) { - switch_status_t status; + switch_status_t status = SWITCH_STATUS_FALSE; switch_size_t want, got, orig_len = *len; switch_assert(fh != NULL); switch_assert(fh->file_interface != NULL); + top: + if (fh->buffer && switch_buffer_inuse(fh->buffer) >= *len * 2) { *len = switch_buffer_read(fh->buffer, data, orig_len * 2) / 2; return SWITCH_STATUS_SUCCESS; } - + + if (switch_test_flag(fh, SWITCH_FILE_DONE)) { + switch_clear_flag(fh, SWITCH_FILE_DONE); + *len = 0; + return SWITCH_STATUS_FALSE; + } + want = *len; more: - if ((status = fh->file_interface->file_read(fh, data, len)) != SWITCH_STATUS_SUCCESS || !*len) { - *len = 0; - goto done; + if (fh->pre_buffer) { + switch_size_t rlen; + if (!switch_test_flag(fh, SWITCH_FILE_BUFFER_DONE)) { + if (!switch_buffer_inuse(fh->pre_buffer)) { + rlen = fh->pre_buffer_datalen / 2; + if ((status = fh->file_interface->file_read(fh, fh->pre_buffer_data, &rlen)) != SWITCH_STATUS_SUCCESS || !rlen) { + switch_set_flag(fh, SWITCH_FILE_BUFFER_DONE); + } else { + switch_buffer_write(fh->pre_buffer, fh->pre_buffer_data, rlen * 2); + } + } + } + + rlen = switch_buffer_read(fh->pre_buffer, data, *len * 2); + *len = rlen / 2; + + if (*len == 0) { + switch_set_flag(fh, SWITCH_FILE_DONE); + goto top; + } else { + status = SWITCH_STATUS_SUCCESS; + } + + } else { + + if ((status = fh->file_interface->file_read(fh, data, len)) != SWITCH_STATUS_SUCCESS || !*len) { + switch_set_flag(fh, SWITCH_FILE_DONE); + goto top; + } } + got = *len; if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->native_rate != fh->samplerate) { @@ -186,8 +227,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh, } - done: - return status; } @@ -234,7 +273,26 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_write(switch_file_handle_t *fh, return SWITCH_STATUS_SUCCESS; } - return fh->file_interface->file_write(fh, data, len); + + if (fh->pre_buffer) { + switch_size_t rlen, blen; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch_buffer_write(fh->pre_buffer, data, *len * 2); + + rlen = switch_buffer_inuse(fh->pre_buffer); + if (rlen >= fh->pre_buffer_datalen) { + blen = switch_buffer_read(fh->pre_buffer, fh->pre_buffer_data, fh->pre_buffer_datalen); + blen /= 2; + if ((status = fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen)) != SWITCH_STATUS_SUCCESS) { + *len = 0; + } + } + + return status; + } else { + return fh->file_interface->file_write(fh, data, len); + } } SWITCH_DECLARE(switch_status_t) switch_core_file_seek(switch_file_handle_t *fh, unsigned int *cur_pos, int64_t samples, int whence) @@ -294,6 +352,21 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh) switch_buffer_destroy(&fh->buffer); } + if (fh->pre_buffer) { + if (switch_test_flag(fh, SWITCH_FILE_FLAG_WRITE)) { + switch_size_t rlen, blen; + while((rlen = switch_buffer_inuse(fh->pre_buffer))) { + blen = switch_buffer_read(fh->pre_buffer, fh->pre_buffer_data, fh->pre_buffer_datalen); + blen /= 2; + if (fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen) != SWITCH_STATUS_SUCCESS) { + break; + } + } + } + + switch_buffer_destroy(&fh->pre_buffer); + } + switch_resample_destroy(&fh->resampler); UNPROTECT_INTERFACE(fh->file_interface); diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 968aaed540..973b45bda3 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -805,7 +805,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess } if (session->write_codec) { - if (write_frame->datalen == session->write_codec->implementation->decoded_bytes_per_packet) { + if (write_frame->codec->implementation->decoded_bytes_per_packet == session->write_codec->implementation->decoded_bytes_per_packet) { perfect = TRUE; } else { if (!session->raw_write_buffer) { @@ -828,6 +828,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess } if (perfect) { + + if (write_frame->datalen < session->write_codec->implementation->decoded_bytes_per_packet) { + memset(write_frame->data, 255, session->write_codec->implementation->decoded_bytes_per_packet - write_frame->datalen); + write_frame->datalen = session->write_codec->implementation->decoded_bytes_per_packet; + } + enc_frame = write_frame; session->enc_write_frame.datalen = session->enc_write_frame.buflen; diff --git a/src/switch_core_session.c b/src/switch_core_session.c index fa51be2459..f67d6a162d 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -110,11 +110,12 @@ SWITCH_DECLARE(void) switch_core_session_hupall_endpoint(const switch_endpoint_i switch_hash_this(hi, NULL, NULL, &val); if (val) { session = (switch_core_session_t *) val; - switch_core_session_read_lock(session); - if (session->endpoint_interface == endpoint_interface) { - switch_channel_hangup(switch_core_session_get_channel(session), cause); + if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) { + if (session->endpoint_interface == endpoint_interface) { + switch_channel_hangup(switch_core_session_get_channel(session), cause); + } + switch_core_session_rwunlock(session); } - switch_core_session_rwunlock(session); } } switch_mutex_unlock(runtime.throttle_mutex); @@ -132,9 +133,10 @@ SWITCH_DECLARE(void) switch_core_session_hupall(switch_call_cause_t cause) switch_hash_this(hi, NULL, NULL, &val); if (val) { session = (switch_core_session_t *) val; - switch_core_session_read_lock(session); - switch_channel_hangup(switch_core_session_get_channel(session), cause); - switch_core_session_rwunlock(session); + if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) { + switch_channel_hangup(switch_core_session_get_channel(session), cause); + switch_core_session_rwunlock(session); + } } } switch_mutex_unlock(runtime.throttle_mutex); @@ -744,13 +746,14 @@ SWITCH_DECLARE(uint32_t) switch_core_session_flush_private_events(switch_core_se return x; } -SWITCH_DECLARE(void) switch_core_session_reset(switch_core_session_t *session, switch_bool_t flush_dtmf) +SWITCH_DECLARE(void) switch_core_session_reset(switch_core_session_t *session, switch_bool_t flush_dtmf, switch_bool_t reset_read_codec) { switch_channel_t *channel = switch_core_session_get_channel(session); switch_size_t has; - - switch_core_session_set_read_codec(session, NULL); + if (reset_read_codec) { + switch_core_session_set_read_codec(session, NULL); + } /* clear resamplers */ switch_mutex_lock(session->resample_mutex); @@ -824,7 +827,7 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t * switch_channel_get_name((*session)->channel), switch_channel_state_name(switch_channel_get_state((*session)->channel))); - switch_core_session_reset(*session, TRUE); + switch_core_session_reset(*session, TRUE, SWITCH_TRUE); switch_core_media_bug_remove_all(*session); switch_ivr_deactivate_unicast(*session); diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index 604cd2edab..9cab8f85c1 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -185,7 +185,7 @@ static void switch_core_standard_on_park(switch_core_session_t *session) { switch_assert(session != NULL); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Standard PARK\n", switch_channel_get_name(session->channel)); - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); switch_ivr_park(session, NULL); } diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 28e0fe5cdc..dfc7c8d1cc 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -1163,7 +1163,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_ max_forwards = switch_core_session_sprintf(session, "%d", forwardval); switch_channel_set_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE, max_forwards); - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); switch_channel_clear_flag(channel, CF_ORIGINATING); /* clear all state handlers */ diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 83519925ce..f3b0aeac72 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -371,7 +371,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_displace_session(switch_core_session_ read_codec->implementation->actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); return SWITCH_STATUS_GENERR; } @@ -794,7 +794,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session switch_core_session_rwunlock(tsession); status = SWITCH_STATUS_SUCCESS; - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); } return status; @@ -842,6 +842,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_session(switch_core_session_t fh->channels = channels; fh->samplerate = read_codec->implementation->actual_samples_per_second; + fh->pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN; if (switch_core_file_open(fh, file, @@ -850,7 +851,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_session(switch_core_session_t SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening %s\n", file); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); return SWITCH_STATUS_GENERR; } @@ -1678,7 +1679,11 @@ static void *SWITCH_THREAD_FUNC speech_thread(switch_thread_t *thread, void *obj switch_thread_cond_create(&sth->cond, sth->pool); switch_mutex_init(&sth->mutex, SWITCH_MUTEX_NESTED, sth->pool); - switch_core_session_read_lock(sth->session); + if (switch_core_session_read_lock(sth->session) != SWITCH_STATUS_SUCCESS) { + sth->ready = 0; + return NULL; + } + switch_mutex_lock(sth->mutex); sth->ready = 1; diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 55f57d41ed..2365ed61e3 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -430,7 +430,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) end: - switch_core_session_reset(session_a, SWITCH_TRUE); + switch_core_session_reset(session_a, SWITCH_TRUE, SWITCH_TRUE); switch_channel_set_variable(chan_a, SWITCH_BRIDGE_VARIABLE, NULL); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BRIDGE THREAD DONE [%s]\n", switch_channel_get_name(chan_a)); if (!inner_bridge) { @@ -451,7 +451,7 @@ static switch_status_t audio_bridge_on_exchange_media(switch_core_session_t *ses switch_channel_set_private(channel, "_bridge_", NULL); if (bd->session == session && *bd->b_uuid) { audio_bridge_thread(NULL, (void *) bd); - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); } else { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); } @@ -581,7 +581,7 @@ static switch_status_t uuid_bridge_on_soft_execute(switch_core_session_t *sessio switch_channel_wait_for_state(channel, other_channel, CS_SOFT_EXECUTE); - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); ready_a = switch_channel_ready(channel); diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 35d562c557..1d9752d36c 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -501,9 +501,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_answer(switch_core_session_t } olen = mlen; - if (ringback.fh->resampler && ringback.fh->resampler->rfactor > 1) { - olen = (switch_size_t) (olen * ringback.fh->resampler->rfactor); - } + //if (ringback.fh->resampler && ringback.fh->resampler->rfactor > 1) { + //olen = (switch_size_t) (olen * ringback.fh->resampler->rfactor); + //} switch_core_file_read(ringback.fh, write_frame.data, &olen); if (olen == 0) { @@ -547,7 +547,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_answer(switch_core_session_t switch_buffer_destroy(&ringback.audio_buffer); } - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); if (write_codec.implementation) { switch_core_codec_destroy(&write_codec); @@ -1128,7 +1128,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess continue; } - switch_core_session_read_lock(new_session); + if (switch_core_session_read_lock(new_session) != SWITCH_STATUS_SUCCESS) { + status = SWITCH_STATUS_FALSE; + goto done; + } pool = NULL; caller_profiles[i] = new_profile; @@ -1473,9 +1476,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } olen = mlen; - if (ringback.fh->resampler && ringback.fh->resampler->rfactor > 1) { - olen = (switch_size_t) (olen * ringback.fh->resampler->rfactor); - } + + //if (ringback.fh->resampler && ringback.fh->resampler->rfactor > 1) { + //olen = (switch_size_t) (olen * ringback.fh->resampler->rfactor); + //} switch_core_file_read(ringback.fh, write_frame.data, &olen); @@ -1527,7 +1531,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess if (session && (ringback_data || !(switch_channel_test_flag(caller_channel, CF_PROXY_MODE) && switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)))) { - switch_core_session_reset(session, SWITCH_FALSE); + switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE); } for (i = 0; i < and_argc; i++) { @@ -1716,7 +1720,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } if (session) { - switch_core_session_reset(session, SWITCH_FALSE); + switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE); } if (write_codec.implementation) { diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index fe7a6b4b1a..34c9669f8b 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -402,7 +402,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se read_codec->implementation->actual_samples_per_second, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); return SWITCH_STATUS_GENERR; } @@ -460,7 +460,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se "Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate, fh->channels, read_codec->implementation->microseconds_per_packet / 1000); switch_core_file_close(fh); - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); return SWITCH_STATUS_GENERR; } @@ -580,7 +580,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se } switch_core_file_close(fh); - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); return status; } @@ -853,7 +853,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess read_codec->implementation->number_of_channels, read_codec->implementation->actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); status = SWITCH_STATUS_NOTFOUND; goto end; } @@ -910,7 +910,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setup buffer failed\n"); switch_core_file_close(fh); - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); status = SWITCH_STATUS_GENERR; goto end; @@ -937,7 +937,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate, fh->channels, interval); switch_core_file_close(fh); - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); status = SWITCH_STATUS_GENERR; goto end; } @@ -953,7 +953,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setup timer failed!\n"); switch_core_codec_destroy(&codec); switch_core_file_close(fh); - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); status = SWITCH_STATUS_GENERR; goto end; } @@ -1238,7 +1238,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess end: switch_safe_free(abuf); - switch_core_session_reset(session, SWITCH_FALSE); + switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE); return status; } @@ -1275,7 +1275,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_silence(switch_core_session_ read_codec->implementation->number_of_channels, read_codec->implementation->actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); return SWITCH_STATUS_NOTFOUND; } switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE); @@ -1362,7 +1362,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_silence(switch_core_session_ } } - switch_core_session_reset(session, SWITCH_FALSE); + switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE); switch_core_codec_destroy(&raw_codec); end: @@ -1835,7 +1835,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses timer_name = switch_channel_get_variable(channel, "timer_name"); - switch_core_session_reset(session, SWITCH_FALSE); + switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE); read_codec = switch_core_session_get_read_codec(session); rate = read_codec->implementation->actual_samples_per_second; @@ -1846,7 +1846,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses if (switch_core_speech_open(sh, tts_name, voice_name, (uint32_t) rate, interval, &flags, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid TTS module!\n"); - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); if (cache_obj) { switch_channel_set_private(channel, SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME, NULL); } @@ -1872,7 +1872,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activation Failed %s@%uhz 1 channel %dms\n", codec_name, rate, interval); flags = 0; switch_core_speech_close(sh, &flags); - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); if (cache_obj) { switch_channel_set_private(channel, SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME, NULL); } @@ -1889,7 +1889,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses switch_core_codec_destroy(write_frame.codec); flags = 0; switch_core_speech_close(sh, &flags); - switch_core_session_reset(session, SWITCH_TRUE); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); if (cache_obj) { switch_channel_set_private(channel, SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME, NULL); } @@ -1918,7 +1918,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses } } - switch_core_session_reset(session, SWITCH_FALSE); + switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE); return status; }