diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index b4ea5a4bc8..b6f4f11554 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -310,7 +310,7 @@ struct switch_file_handle { /*! the current native samplerate */ uint32_t native_rate; /*! the number of channels */ - uint8_t channels; + uint32_t channels; /*! integer representation of the format */ unsigned int format; /*! integer representation of the sections */ @@ -353,6 +353,8 @@ struct switch_file_handle { const char *prefix; int max_samples; switch_event_t *params; + uint32_t cur_channels; + uint32_t cur_samplerate; }; /*! \brief Abstract interface to an asr module */ diff --git a/src/include/switch_types.h b/src/include/switch_types.h index bdbf219957..8689d74bbf 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1581,7 +1581,8 @@ typedef enum { SWITCH_FILE_BUFFER_DONE = (1 << 14), SWITCH_FILE_WRITE_APPEND = (1 << 15), SWITCH_FILE_WRITE_OVER = (1 << 16), - SWITCH_FILE_NOMUX = (1 << 17) + SWITCH_FILE_NOMUX = (1 << 17), + SWITCH_FILE_BREAK_ON_CHANGE = (1 << 18) } switch_file_flag_enum_t; typedef uint32_t switch_file_flag_t; diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 95aea27f87..d5686b918c 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -4509,8 +4509,8 @@ static switch_status_t next_file(switch_file_handle_t *handle) } handle->samples = context->fh.samples; - //handle->samplerate = context->fh.samplerate; - //handle->channels = context->fh.channels; + handle->cur_samplerate = context->fh.samplerate; + handle->cur_channels = context->fh.channels; handle->format = context->fh.format; handle->sections = context->fh.sections; handle->seekable = context->fh.seekable; @@ -4518,6 +4518,7 @@ static switch_status_t next_file(switch_file_handle_t *handle) handle->interval = context->fh.interval; handle->max_samples = 0; + if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) { switch_set_flag(handle, SWITCH_FILE_NATIVE); } else { @@ -4602,8 +4603,13 @@ static switch_status_t file_string_file_read(switch_file_handle_t *handle, void if ((status = next_file(handle)) != SWITCH_STATUS_SUCCESS) { return status; } - *len = llen; - status = switch_core_file_read(&context->fh, data, len); + if (switch_test_flag(handle, SWITCH_FILE_BREAK_ON_CHANGE)) { + *len = 0; + status = SWITCH_STATUS_BREAK; + } else { + *len = llen; + status = switch_core_file_read(&context->fh, data, len); + } } return status; diff --git a/src/switch_core_file.c b/src/switch_core_file.c index 9c4ae53cc2..bee78e2643 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -292,7 +292,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh, rlen = asis ? fh->pre_buffer_datalen : fh->pre_buffer_datalen / 2; if (switch_buffer_inuse(fh->pre_buffer) < rlen * 2) { - if ((status = fh->file_interface->file_read(fh, fh->pre_buffer_data, &rlen)) != SWITCH_STATUS_SUCCESS || !rlen) { + if ((status = fh->file_interface->file_read(fh, fh->pre_buffer_data, &rlen)) == SWITCH_STATUS_BREAK) { + return SWITCH_STATUS_BREAK; + } + + + if (status != SWITCH_STATUS_SUCCESS || !rlen) { switch_set_flag(fh, SWITCH_FILE_BUFFER_DONE); } else { fh->samples_in += rlen; @@ -316,7 +321,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh, } else { - if ((status = fh->file_interface->file_read(fh, data, len)) != SWITCH_STATUS_SUCCESS || !*len) { + if ((status = fh->file_interface->file_read(fh, data, len)) == SWITCH_STATUS_BREAK) { + return SWITCH_STATUS_BREAK; + } + + if (status != SWITCH_STATUS_SUCCESS || !*len) { switch_set_flag(fh, SWITCH_FILE_DONE); goto top; } diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 22bc84a7dd..f98b8f77de 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -1049,6 +1049,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess int more_data = 0; switch_event_t *event; uint32_t test_native = 0, last_native = 0; + uint32_t buflen = 0; if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_FALSE; @@ -1110,6 +1111,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess fh->samples = 0; } + + + for (cur = 0; switch_channel_ready(channel) && !done && cur < argc; cur++) { file = argv[cur]; eof = 0; @@ -1255,9 +1259,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess if (!abuf) { - switch_zmalloc(abuf, FILE_STARTSAMPLES * sizeof(*abuf) * fh->channels); + buflen = write_frame.buflen = FILE_STARTSAMPLES * sizeof(*abuf) * fh->channels; + switch_zmalloc(abuf, write_frame.buflen); write_frame.data = abuf; - write_frame.buflen = FILE_STARTSAMPLES; } if (sample_start > 0) { @@ -1454,6 +1458,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess } } + buflen = FILE_STARTSAMPLES * sizeof(*abuf) * fh->cur_channels; + + if (buflen > write_frame.buflen) { + abuf = realloc(abuf, buflen); + write_frame.data = abuf; + write_frame.buflen = buflen; + } + if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) { if (framelen > FILE_STARTSAMPLES) { framelen = FILE_STARTSAMPLES; @@ -1493,6 +1505,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess olen = switch_test_flag(fh, SWITCH_FILE_NATIVE) ? framelen : ilen; } else { + switch_status_t rstatus; + if (eof) { break; } @@ -1500,7 +1514,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess if (!switch_test_flag(fh, SWITCH_FILE_NATIVE)) { olen /= 2; } - if (switch_core_file_read(fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) { + switch_set_flag(fh, SWITCH_FILE_BREAK_ON_CHANGE); + if ((rstatus = switch_core_file_read(fh, abuf, &olen)) == SWITCH_STATUS_BREAK) { + continue; + } + + if (rstatus != SWITCH_STATUS_SUCCESS) { eof++; continue; }