From c711a508466569b814f2c80baf3e3c0587d47a7f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 10 Jan 2009 03:52:28 +0000 Subject: [PATCH] fix double close of filehandles and add recording of native files git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11108 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- .../mod_local_stream/mod_local_stream.c | 2 +- src/switch_core_file.c | 25 ++++-- src/switch_ivr_play_say.c | 83 +++++++++++++------ 3 files changed, 75 insertions(+), 35 deletions(-) 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 adad6e5f39..a5c82cbb64 100644 --- a/src/mod/formats/mod_local_stream/mod_local_stream.c +++ b/src/mod/formats/mod_local_stream/mod_local_stream.c @@ -251,7 +251,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void done: - if (fh.file_interface) { + if (switch_test_flag((&fh), SWITCH_FILE_OPEN)) { switch_core_file_close(&fh); } diff --git a/src/switch_core_file.c b/src/switch_core_file.c index 2914ffedc8..a5042cea64 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -132,7 +132,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh, { 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); @@ -155,19 +155,21 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh, if (fh->pre_buffer) { switch_size_t rlen; + int asis = switch_test_flag(fh, SWITCH_FILE_NATIVE); + if (!switch_test_flag(fh, SWITCH_FILE_BUFFER_DONE)) { if (!switch_buffer_inuse(fh->pre_buffer)) { - rlen = fh->pre_buffer_datalen / 2; + rlen = asis ? fh->pre_buffer_datalen : 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); + switch_buffer_write(fh->pre_buffer, fh->pre_buffer_data, asis ? rlen : rlen * 2); } } } - rlen = switch_buffer_read(fh->pre_buffer, data, *len * 2); - *len = rlen / 2; + rlen = switch_buffer_read(fh->pre_buffer, data, asis ? *len : *len * 2); + *len = asis ? rlen : rlen / 2; if (*len == 0) { switch_set_flag(fh, SWITCH_FILE_DONE); @@ -277,13 +279,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_write(switch_file_handle_t *fh, if (fh->pre_buffer) { switch_size_t rlen, blen; switch_status_t status = SWITCH_STATUS_SUCCESS; + int asis = switch_test_flag(fh, SWITCH_FILE_NATIVE); - switch_buffer_write(fh->pre_buffer, data, *len * 2); + switch_buffer_write(fh->pre_buffer, data, asis ? *len : *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 (!asis) blen /= 2; if ((status = fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen)) != SWITCH_STATUS_SUCCESS) { *len = 0; } @@ -345,6 +348,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh) switch_assert(fh != NULL); switch_assert(fh->file_interface != NULL); + if (!switch_test_flag(fh, SWITCH_FILE_OPEN)) { + return SWITCH_STATUS_FALSE; + } + switch_clear_flag(fh, SWITCH_FILE_OPEN); status = fh->file_interface->file_close(fh); @@ -355,9 +362,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh) if (fh->pre_buffer) { if (switch_test_flag(fh, SWITCH_FILE_FLAG_WRITE)) { switch_size_t rlen, blen; + int asis = switch_test_flag(fh, SWITCH_FILE_NATIVE); + 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 (asis) blen /= 2; if (fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen) != SWITCH_STATUS_SUCCESS) { break; } diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 34c9669f8b..7429de95c4 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -384,6 +384,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se const char *vval; time_t start = 0; uint32_t org_silence_hits = 0; + int asis = 0; switch_assert(read_codec != NULL); @@ -396,6 +397,30 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se fh->channels = read_codec->implementation->number_of_channels; fh->native_rate = read_codec->implementation->actual_samples_per_second; + + + if (!strstr(file, SWITCH_URL_SEPARATOR)) { + char *ext; + const char *prefix; + + prefix = switch_channel_get_variable(channel, "sound_prefix"); + if (!prefix) { + prefix = SWITCH_GLOBAL_dirs.base_dir; + } + + if (!switch_is_file_path(file)) { + file = switch_core_session_sprintf(session, "%s%s%s", prefix, SWITCH_PATH_SEPARATOR, file); + } + if ((ext = strrchr(file, '.'))) { + ext++; + } else { + ext = read_codec->implementation->iananame; + file = switch_core_session_sprintf(session, "%s.%s", file, ext); + asis = 1; + } + } + + if (switch_core_file_open(fh, file, fh->channels, @@ -444,37 +469,43 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se switch_channel_set_variable(channel, "RECORD_DATE", NULL); } - codec_name = "L16"; - if (switch_core_codec_init(&codec, - codec_name, - NULL, - read_codec->implementation->actual_samples_per_second, - read_codec->implementation->microseconds_per_packet / 1000, - read_codec->implementation->number_of_channels, - SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, - switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activated\n"); - switch_core_session_set_read_codec(session, &codec); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "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_TRUE); - return SWITCH_STATUS_GENERR; + if (!asis) { + codec_name = "L16"; + if (switch_core_codec_init(&codec, + codec_name, + NULL, + read_codec->implementation->actual_samples_per_second, + read_codec->implementation->microseconds_per_packet / 1000, + read_codec->implementation->number_of_channels, + SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, + switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activated\n"); + switch_core_session_set_read_codec(session, &codec); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "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_TRUE); + return SWITCH_STATUS_GENERR; + } } if (limit) { start = switch_timestamp(NULL); } - + if (fh->thresh) { - if (fh->silence_hits) { - fh->silence_hits = fh->samplerate * fh->silence_hits / read_codec->implementation->samples_per_packet; + if (asis) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't detect silence on a native recording.\n"); } else { - fh->silence_hits = fh->samplerate * 3 / read_codec->implementation->samples_per_packet; + if (fh->silence_hits) { + fh->silence_hits = fh->samplerate * fh->silence_hits / read_codec->implementation->samples_per_packet; + } else { + fh->silence_hits = fh->samplerate * 3 / read_codec->implementation->samples_per_packet; + } + org_silence_hits = fh->silence_hits; } - org_silence_hits = fh->silence_hits; } for (;;) { @@ -543,7 +574,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se } } - if (fh->thresh) { + if (!asis && fh->thresh) { int16_t *fdata = (int16_t *) read_frame->data; uint32_t samples = read_frame->datalen / sizeof(*fdata); uint32_t score, count = 0, j = 0; @@ -571,8 +602,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se if (!switch_test_flag(fh, SWITCH_FILE_PAUSE) && !switch_test_flag(read_frame, SFF_CNG)) { int16_t *data = read_frame->data; - len = (switch_size_t) read_frame->datalen / 2; - + len = (switch_size_t) asis ? read_frame->datalen : read_frame->datalen / 2; + if (switch_core_file_write(fh, data, &len) != SWITCH_STATUS_SUCCESS) { break; }