switch_ivr_play_say.c File Reference

#include <switch.h>

Include dependency graph for switch_ivr_play_say.c:

Go to the source code of this file.

Data Structures

struct  cached_speech_handle

Defines

#define FILE_STARTSAMPLES   1024 * 32
#define FILE_BLOCKSIZE   1024 * 8
#define FILE_BUFSIZE   1024 * 64

Typedefs

typedef cached_speech_handle cached_speech_handle_t

Functions

switch_status_t switch_ivr_phrase_macro_event (switch_core_session_t *session, const char *macro_name, const char *data, switch_event_t *event, const char *lang, switch_input_args_t *args)
switch_status_t switch_ivr_record_file (switch_core_session_t *session, switch_file_handle_t *fh, const char *file, switch_input_args_t *args, uint32_t limit)
static int teletone_handler (teletone_generation_session_t *ts, teletone_tone_map_t *map)
switch_status_t switch_ivr_gentones (switch_core_session_t *session, const char *script, int32_t loops, switch_input_args_t *args)
switch_status_t switch_ivr_get_file_handle (switch_core_session_t *session, switch_file_handle_t **fh)
switch_status_t switch_ivr_release_file_handle (switch_core_session_t *session, switch_file_handle_t **fh)
static void add_playback_vars_to_event (switch_core_session_t *session, switch_event_t *event, char *vars)
switch_status_t switch_ivr_play_file (switch_core_session_t *session, switch_file_handle_t *fh, const char *file, switch_input_args_t *args)
 play a file from the disk to the session
switch_status_t switch_ivr_wait_for_silence (switch_core_session_t *session, uint32_t thresh, uint32_t silence_hits, uint32_t listen_hits, uint32_t timeout_ms, const char *file)
switch_status_t switch_ivr_read (switch_core_session_t *session, uint32_t min_digits, uint32_t max_digits, const char *prompt_audio_file, const char *var_name, char *digit_buffer, switch_size_t digit_buffer_length, uint32_t timeout, const char *valid_terminators, uint32_t digit_timeout)
switch_status_t switch_play_and_get_digits (switch_core_session_t *session, uint32_t min_digits, uint32_t max_digits, uint32_t max_tries, uint32_t timeout, const char *valid_terminators, const char *prompt_audio_file, const char *bad_input_audio_file, const char *var_name, char *digit_buffer, uint32_t digit_buffer_length, const char *digits_regex, uint32_t digit_timeout, const char *transfer_on_failure)
 Play a sound and gather digits with the number of retries specified if the user doesn't give digits in the set time.
switch_status_t switch_ivr_speak_text_handle (switch_core_session_t *session, switch_speech_handle_t *sh, switch_codec_t *codec, switch_timer_t *timer, char *text, switch_input_args_t *args)
void switch_ivr_clear_speech_cache (switch_core_session_t *session)
switch_status_t switch_ivr_speak_text (switch_core_session_t *session, const char *tts_name, const char *voice_name, char *text, switch_input_args_t *args)
 Speak given text with given tts engine.
static switch_status_t hold_on_dtmf (switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
switch_status_t switch_ivr_soft_hold (switch_core_session_t *session, const char *unhold_key, const char *moh_a, const char *moh_b)


Define Documentation

#define FILE_BLOCKSIZE   1024 * 8

Definition at line 979 of file switch_ivr_play_say.c.

Referenced by switch_ivr_play_file().

#define FILE_BUFSIZE   1024 * 64

Definition at line 980 of file switch_ivr_play_say.c.

Referenced by switch_ivr_play_file().

#define FILE_STARTSAMPLES   1024 * 32

Definition at line 978 of file switch_ivr_play_say.c.

Referenced by switch_ivr_play_file().


Typedef Documentation

typedef struct cached_speech_handle cached_speech_handle_t

Definition at line 2375 of file switch_ivr_play_say.c.


Function Documentation

static void add_playback_vars_to_event ( switch_core_session_t session,
switch_event_t event,
char *  vars 
) [static]

Definition at line 982 of file switch_ivr_play_say.c.

References switch_core_session_sprintf(), switch_core_session_strdup, switch_event_add_header_string(), switch_separate_string(), and SWITCH_STACK_BOTTOM.

Referenced by switch_ivr_play_file().

00983 {
00984         char *tmp;
00985 
00986         if (!session || !event || !vars)
00987                 return;
00988 
00989         if ((tmp = switch_core_session_strdup(session, vars))) {
00990                 char *argv[128] = { 0 };
00991                 int argc, i;
00992 
00993                 if (!(argc = switch_separate_string(tmp, ',', argv, (sizeof(argv) / sizeof(argv[0])))))
00994                         return;
00995 
00996                 for (i = 0; i < argc; i++) {
00997                         char *var, *val;
00998 
00999                         if ((var = strchr(argv[i], '='))) {
01000                                 *var = '\0';
01001                                 val = var+1;
01002                                 var = argv[i];
01003 
01004                                 if (var && *var && val && *val) {
01005                                         if ((var = switch_core_session_sprintf(session, "playback_variable_%s", var))) {
01006                                                 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, var, val);
01007                                         }
01008                                 }
01009                         }
01010                 }
01011         }
01012 }

static switch_status_t hold_on_dtmf ( switch_core_session_t session,
void *  input,
switch_input_type_t  itype,
void *  buf,
unsigned int  buflen 
) [static]

Definition at line 2538 of file switch_ivr_play_say.c.

References switch_dtmf_t::digit, SWITCH_INPUT_TYPE_DTMF, SWITCH_STATUS_BREAK, and SWITCH_STATUS_SUCCESS.

Referenced by switch_ivr_soft_hold().

02539 {
02540         char *stop_key = (char *) buf;
02541 
02542         switch (itype) {
02543         case SWITCH_INPUT_TYPE_DTMF:
02544                 {
02545                         switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
02546                         if (dtmf->digit == *stop_key) {
02547                                 return SWITCH_STATUS_BREAK;
02548                         }
02549                 }
02550                 break;
02551         default:
02552                 break;
02553         }
02554 
02555         return SWITCH_STATUS_SUCCESS;
02556 }

switch_status_t switch_ivr_record_file ( switch_core_session_t session,
switch_file_handle_t fh,
const char *  file,
switch_input_args_t args,
uint32_t  limit 
)

Definition at line 356 of file switch_ivr_play_say.c.

References switch_codec_implementation::actual_samples_per_second, switch_frame::buflen, CF_BREAK, switch_file_handle::channels, switch_frame::codec, switch_stream_handle::data, switch_frame::data, switch_frame::datalen, switch_codec_implementation::decoded_bytes_per_packet, switch_dtmf_t::digit, switch_codec_implementation::iananame, switch_codec_implementation::microseconds_per_packet, switch_codec_implementation::number_of_channels, switch_frame::samples, switch_codec_implementation::samples_per_packet, SFF_CNG, switch_directories::sounds_dir, switch_api_execute(), SWITCH_AUDIO_COL_STR_ARTIST, SWITCH_AUDIO_COL_STR_COMMENT, SWITCH_AUDIO_COL_STR_COPYRIGHT, SWITCH_AUDIO_COL_STR_DATE, SWITCH_AUDIO_COL_STR_SOFTWARE, SWITCH_AUDIO_COL_STR_TITLE, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, switch_channel_answer, switch_channel_clear_flag(), switch_channel_dequeue_dtmf(), switch_channel_event_set_data(), switch_channel_expand_variables, switch_channel_get_variable, switch_channel_hangup, switch_channel_has_dtmf(), switch_channel_media_ready, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_variable, switch_channel_set_variable_printf(), switch_channel_test_flag(), switch_clear_flag, SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, switch_core_codec_destroy(), switch_core_codec_init, switch_core_file_close(), switch_core_file_open, switch_core_file_seek(), switch_core_file_set_string(), switch_core_file_write(), switch_core_session_dequeue_event(), switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_impl(), switch_core_session_read_frame(), switch_core_session_reset(), switch_core_session_set_read_codec(), switch_core_session_sprintf(), switch_core_session_strdup, switch_core_session_write_frame(), SWITCH_DEFAULT_FILE_BUFFER_LEN, switch_epoch_time_now(), switch_event_add_header_string(), switch_event_create, switch_event_destroy(), switch_event_fire, SWITCH_EVENT_RECORD_START, SWITCH_EVENT_RECORD_STOP, SWITCH_FALSE, SWITCH_FILE_DATA_SHORT, SWITCH_FILE_FLAG_WRITE, SWITCH_FILE_NATIVE, SWITCH_FILE_PAUSE, SWITCH_FILE_SEEK, SWITCH_FILE_WRITE_APPEND, SWITCH_FILE_WRITE_OVER, switch_find_end_paren(), switch_generate_sln_silence(), SWITCH_GLOBAL_dirs, SWITCH_INPUT_TYPE_DTMF, SWITCH_INPUT_TYPE_EVENT, SWITCH_IO_FLAG_NONE, switch_is_file_path(), switch_is_valid_rate, switch_ivr_dmachine_feed(), switch_ivr_dmachine_ping(), switch_ivr_parse_all_events(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_PATH_SEPARATOR, SWITCH_READ_ACCEPTABLE, SWITCH_RECOMMENDED_BUFFER_SIZE, switch_safe_free, SWITCH_STACK_BOTTOM, SWITCH_STANDARD_STREAM, SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, SWITCH_STATUS_SUCCESS, switch_str_nil, switch_test_flag, SWITCH_TRUE, switch_true(), SWITCH_URL_SEPARATOR, and write_buf().

00358 {
00359         switch_channel_t *channel = switch_core_session_get_channel(session);
00360         switch_dtmf_t dtmf = { 0 };
00361         switch_file_handle_t lfh = { 0 };
00362         switch_frame_t *read_frame;
00363         switch_codec_t codec, write_codec = { 0 };
00364         char *codec_name;
00365         switch_status_t status = SWITCH_STATUS_SUCCESS;
00366         const char *p;
00367         const char *vval;
00368         time_t start = 0;
00369         uint32_t org_silence_hits = 0;
00370         int asis = 0;
00371         int32_t sample_start = 0;
00372         int waste_resources = 0, fill_cng = 0;
00373         switch_codec_implementation_t read_impl = { 0 };
00374         switch_frame_t write_frame = { 0 };
00375         unsigned char write_buf[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 };
00376         switch_event_t *event;
00377         int divisor = 0;
00378         int file_flags = SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT;
00379         int restart_limit_on_dtmf = 0;
00380         const char *prefix, *var;
00381 
00382         prefix = switch_channel_get_variable(channel, "sound_prefix");
00383 
00384         if (!prefix) {
00385                 prefix = SWITCH_GLOBAL_dirs.sounds_dir;
00386         }
00387 
00388         switch_core_session_get_read_impl(session, &read_impl);
00389 
00390         if (!(divisor = read_impl.actual_samples_per_second / 8000)) {
00391                 divisor = 1;
00392         }
00393 
00394 
00395         if (!switch_channel_ready(channel)) {
00396                 return SWITCH_STATUS_FALSE;
00397         }
00398 
00399         if (switch_channel_answer(channel) != SWITCH_STATUS_SUCCESS) {
00400                 return SWITCH_STATUS_FALSE;
00401         }
00402 
00403         if (!switch_channel_media_ready(channel)) {
00404                 return SWITCH_STATUS_FALSE;
00405         }
00406 
00407         if (!fh) {
00408                 fh = &lfh;
00409         }
00410 
00411         fh->channels = read_impl.number_of_channels;
00412         fh->native_rate = read_impl.actual_samples_per_second;
00413 
00414         if (fh->samples > 0) {
00415                 sample_start = fh->samples;
00416                 fh->samples = 0;
00417         }
00418 
00419         if ((vval = switch_channel_get_variable(channel, "record_sample_rate"))) {
00420                 int tmp = 0;
00421 
00422                 tmp = atoi(vval);
00423 
00424                 if (switch_is_valid_rate(tmp)) {
00425                         fh->samplerate = tmp;
00426                 }
00427         }
00428 
00429         
00430         if ((vval = switch_channel_get_variable(channel, "record_fill_cng"))) {
00431 
00432                 if (!strcasecmp(vval, "true")) {
00433                         fill_cng = 1400;
00434                 } else {
00435                         if ((fill_cng = atoi(vval)) < 0) {
00436                                 fill_cng = 0;
00437                         }
00438                 }
00439         }
00440         
00441 
00442         if ((vval = switch_channel_get_variable(channel, "record_waste_resources"))) {
00443 
00444                 if (!strcasecmp(vval, "true")) {
00445                         waste_resources = 1400;
00446                 } else {
00447                         if ((waste_resources = atoi(vval)) < 0) {
00448                                 waste_resources = 0;
00449                         }
00450                 }
00451         }
00452 
00453 
00454         if (fill_cng || waste_resources) {
00455                 if (switch_core_codec_init(&write_codec,
00456                                                                    "L16",
00457                                                                    NULL,
00458                                                                    read_impl.actual_samples_per_second,
00459                                                                    read_impl.microseconds_per_packet / 1000,
00460                                                                    read_impl.number_of_channels,
00461                                                                    SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
00462                                                                    switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
00463                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activated, ready to waste resources!\n");
00464                         write_frame.data = write_buf;
00465                         write_frame.buflen = sizeof(write_buf);
00466                         write_frame.datalen = read_impl.decoded_bytes_per_packet;
00467                         write_frame.samples = write_frame.datalen / 2;
00468                         write_frame.codec = &write_codec;
00469                 } else {
00470                         return SWITCH_STATUS_FALSE;
00471                 }
00472         }
00473 
00474         if (!strstr(file, SWITCH_URL_SEPARATOR)) {
00475                 char *ext;
00476 
00477                 if (!switch_is_file_path(file)) {
00478                         char *tfile = NULL;
00479                         char *e;
00480 
00481                         if (*file == '[') {
00482                                 tfile = switch_core_session_strdup(session, file);
00483                                 if ((e = switch_find_end_paren(tfile, '[', ']'))) {
00484                                         *e = '\0';
00485                                         file = e + 1;
00486                                 } else {
00487                                         tfile = NULL;
00488                                 }
00489                         }
00490 
00491                         file = switch_core_session_sprintf(session, "%s%s%s%s%s", switch_str_nil(tfile), tfile ? "]" : "", prefix, SWITCH_PATH_SEPARATOR, file);
00492                 }
00493                 if ((ext = strrchr(file, '.'))) {
00494                         ext++;
00495                 } else {
00496                         ext = read_impl.iananame;
00497                         file = switch_core_session_sprintf(session, "%s.%s", file, ext);
00498                         asis = 1;
00499                 }
00500         }
00501 
00502         vval = switch_channel_get_variable(channel, "enable_file_write_buffering");
00503         if (!vval || switch_true(vval)) {
00504                 fh->pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN;
00505         }
00506 
00507         if (switch_test_flag(fh, SWITCH_FILE_WRITE_APPEND) || ((p = switch_channel_get_variable(channel, "RECORD_APPEND")) && switch_true(p))) {
00508                 file_flags |= SWITCH_FILE_WRITE_APPEND;
00509         }
00510 
00511         if (switch_test_flag(fh, SWITCH_FILE_WRITE_OVER) || ((p = switch_channel_get_variable(channel, "RECORD_WRITE_OVER")) && switch_true(p))) {
00512                 file_flags |= SWITCH_FILE_WRITE_OVER;
00513         }
00514 
00515         if (!fh->prefix) {
00516                 fh->prefix = prefix;
00517         }
00518 
00519         if (switch_core_file_open(fh, file, fh->channels, read_impl.actual_samples_per_second, file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
00520                 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
00521                 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
00522                 return SWITCH_STATUS_GENERR;
00523         }
00524 
00525         if (sample_start > 0) {
00526                 uint32_t pos = 0;
00527                 switch_core_file_seek(fh, &pos, sample_start, SEEK_SET);
00528                 switch_clear_flag(fh, SWITCH_FILE_SEEK);        
00529                 fh->samples = 0;
00530         }
00531 
00532 
00533         if (switch_test_flag(fh, SWITCH_FILE_NATIVE)) {
00534                 asis = 1;
00535         }
00536         
00537         restart_limit_on_dtmf = switch_true(switch_channel_get_variable(channel, "record_restart_limit_on_dtmf"));
00538 
00539         if ((p = switch_channel_get_variable(channel, "RECORD_TITLE"))) {
00540                 vval = switch_core_session_strdup(session, p);
00541                 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_TITLE, vval);
00542                 switch_channel_set_variable(channel, "RECORD_TITLE", NULL);
00543         }
00544 
00545         if ((p = switch_channel_get_variable(channel, "RECORD_COPYRIGHT"))) {
00546                 vval = switch_core_session_strdup(session, p);
00547                 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COPYRIGHT, vval);
00548                 switch_channel_set_variable(channel, "RECORD_COPYRIGHT", NULL);
00549         }
00550 
00551         if ((p = switch_channel_get_variable(channel, "RECORD_SOFTWARE"))) {
00552                 vval = switch_core_session_strdup(session, p);
00553                 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_SOFTWARE, vval);
00554                 switch_channel_set_variable(channel, "RECORD_SOFTWARE", NULL);
00555         }
00556 
00557         if ((p = switch_channel_get_variable(channel, "RECORD_ARTIST"))) {
00558                 vval = switch_core_session_strdup(session, p);
00559                 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_ARTIST, vval);
00560                 switch_channel_set_variable(channel, "RECORD_ARTIST", NULL);
00561         }
00562 
00563         if ((p = switch_channel_get_variable(channel, "RECORD_COMMENT"))) {
00564                 vval = switch_core_session_strdup(session, p);
00565                 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COMMENT, vval);
00566                 switch_channel_set_variable(channel, "RECORD_COMMENT", NULL);
00567         }
00568 
00569         if ((p = switch_channel_get_variable(channel, "RECORD_DATE"))) {
00570                 vval = switch_core_session_strdup(session, p);
00571                 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_DATE, vval);
00572                 switch_channel_set_variable(channel, "RECORD_DATE", NULL);
00573         }
00574 
00575         if (!asis) {
00576                 codec_name = "L16";
00577                 if (switch_core_codec_init(&codec,
00578                                                                    codec_name,
00579                                                                    NULL,
00580                                                                    read_impl.actual_samples_per_second,
00581                                                                    read_impl.microseconds_per_packet / 1000,
00582                                                                    read_impl.number_of_channels,
00583                                                                    SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
00584                                                                    switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
00585                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activated\n");
00586                         switch_core_session_set_read_codec(session, &codec);
00587                 } else {
00588                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
00589                                                           "Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate,
00590                                                           fh->channels, read_impl.microseconds_per_packet / 1000);
00591                         switch_core_file_close(fh);
00592                         switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
00593                         return SWITCH_STATUS_GENERR;
00594                 }
00595         }
00596 
00597         if (limit) {
00598                 start = switch_epoch_time_now(NULL);
00599         }
00600 
00601         if (fh->thresh) {
00602                 if (asis) {
00603                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Can't detect silence on a native recording.\n");
00604                 } else {
00605                         if (fh->silence_hits) {
00606                                 fh->silence_hits = fh->samplerate * fh->silence_hits / read_impl.samples_per_packet;
00607                         } else {
00608                                 fh->silence_hits = fh->samplerate * 3 / read_impl.samples_per_packet;
00609                         }
00610                         org_silence_hits = fh->silence_hits;
00611                 }
00612         }
00613 
00614 
00615         if (switch_event_create(&event, SWITCH_EVENT_RECORD_START) == SWITCH_STATUS_SUCCESS) {
00616                 switch_channel_event_set_data(channel, event);
00617                 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-File-Path", file);
00618                 switch_event_fire(&event);
00619         }
00620 
00621         for (;;) {
00622                 switch_size_t len;
00623 
00624                 if (!switch_channel_ready(channel)) {
00625                         status = SWITCH_STATUS_FALSE;
00626                         break;
00627                 }
00628 
00629                 if (switch_channel_test_flag(channel, CF_BREAK)) {
00630                         switch_channel_clear_flag(channel, CF_BREAK);
00631                         status = SWITCH_STATUS_BREAK;
00632                         break;
00633                 }
00634 
00635                 switch_ivr_parse_all_events(session);
00636 
00637                 if (start && (switch_epoch_time_now(NULL) - start) > limit) {
00638                         break;
00639                 }
00640 
00641                 if (args) {
00642                         /*
00643                            dtmf handler function you can hook up to be executed when a digit is dialed during playback 
00644                            if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
00645                          */
00646                         if (switch_channel_has_dtmf(channel)) {
00647 
00648                                 if (limit && restart_limit_on_dtmf) {
00649                                         start = switch_epoch_time_now(NULL);
00650                                 }
00651 
00652                                 if (!args->input_callback && !args->buf && !args->dmachine) {
00653                                         status = SWITCH_STATUS_BREAK;
00654                                         break;
00655                                 }
00656                                 switch_channel_dequeue_dtmf(channel, &dtmf);
00657 
00658                                 if (args->dmachine) {
00659                                         char ds[2] = {dtmf.digit, '\0'};
00660                                         if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
00661                                                 break;
00662                                         }
00663                                 } 
00664 
00665                                 if (args->input_callback) {
00666                                         status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
00667                                 } else if (args->buf) {
00668                                         *((char *) args->buf) = dtmf.digit;
00669                                         status = SWITCH_STATUS_BREAK;
00670                                 }
00671                         }
00672 
00673                         if (args->input_callback) {
00674                                 switch_event_t *event = NULL;
00675 
00676                                 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
00677                                         status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
00678                                         switch_event_destroy(&event);
00679                                 }
00680                         }
00681 
00682                         if (status != SWITCH_STATUS_SUCCESS) {
00683                                 break;
00684                         }
00685                 }
00686 
00687                 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
00688                 if (!SWITCH_READ_ACCEPTABLE(status)) {
00689                         break;
00690                 }
00691 
00692                 if (args && args->dmachine) {
00693                         if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
00694                                 break;
00695                         }
00696                 }
00697 
00698                 if (args && (args->read_frame_callback)) {
00699                         if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
00700                                 break;
00701                         }
00702                 }
00703 
00704                 if (!asis && fh->thresh) {
00705                         int16_t *fdata = (int16_t *) read_frame->data;
00706                         uint32_t samples = read_frame->datalen / sizeof(*fdata);
00707                         uint32_t score, count = 0, j = 0;
00708                         double energy = 0;
00709 
00710 
00711                         for (count = 0; count < samples; count++) {
00712                                 energy += abs(fdata[j]);
00713                                 j += read_impl.number_of_channels;
00714                         }
00715 
00716                         score = (uint32_t) (energy / (samples / divisor));
00717 
00718                         if (score < fh->thresh) {
00719                                 if (!--fh->silence_hits) {
00720                                         break;
00721                                 }
00722                         } else {
00723                                 fh->silence_hits = org_silence_hits;
00724                         }
00725                 }
00726 
00727                 if (fill_cng) {
00728                         switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, fill_cng);
00729                 } else if (waste_resources) {
00730                         switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, waste_resources);
00731                 }
00732 
00733                 if (!switch_test_flag(fh, SWITCH_FILE_PAUSE) && !switch_test_flag(read_frame, SFF_CNG)) {
00734                         int16_t *data = read_frame->data;
00735                         len = (switch_size_t) asis ? read_frame->datalen : read_frame->datalen / 2;
00736 
00737                         if (switch_core_file_write(fh, data, &len) != SWITCH_STATUS_SUCCESS) {
00738                                 break;
00739                         }
00740                 } else if (switch_test_flag(read_frame, SFF_CNG) && fill_cng) {
00741                         len = write_frame.datalen / 2;
00742                         if (switch_core_file_write(fh, write_frame.data, &len) != SWITCH_STATUS_SUCCESS) {
00743                                 break;
00744                         }                       
00745                 }
00746 
00747                 if (waste_resources) {
00748                         if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
00749                                 break;
00750                         }
00751                 }
00752 
00753         }
00754 
00755         if (fill_cng || waste_resources) {
00756                 switch_core_codec_destroy(&write_codec);
00757         }
00758 
00759         switch_core_file_close(fh);
00760 
00761 
00762         if ((var = switch_channel_get_variable(channel, "record_post_process_exec_api"))) {
00763                 char *cmd = switch_core_session_strdup(session, var);
00764                 char *data, *expanded = NULL;
00765                 switch_stream_handle_t stream = { 0 };
00766                 
00767                 SWITCH_STANDARD_STREAM(stream);
00768                 
00769                 if ((data = strchr(cmd, ':'))) {
00770                         *data++ = '\0';
00771                         expanded = switch_channel_expand_variables(channel, data);
00772                 }
00773                 
00774                 switch_api_execute(cmd, expanded, session, &stream);
00775                 
00776                 if (expanded && expanded != data) {
00777                         free(expanded);
00778                 }
00779                 
00780                 switch_safe_free(stream.data);
00781                 
00782         }
00783 
00784         if (read_impl.actual_samples_per_second) {
00785                 switch_channel_set_variable_printf(channel, "record_seconds", "%d", fh->samples_out / read_impl.actual_samples_per_second);
00786                 switch_channel_set_variable_printf(channel, "record_ms", "%d", fh->samples_out / (read_impl.actual_samples_per_second / 1000));
00787 
00788         }
00789 
00790         switch_channel_set_variable_printf(channel, "record_samples", "%d", fh->samples_out);
00791 
00792         if (switch_event_create(&event, SWITCH_EVENT_RECORD_STOP) == SWITCH_STATUS_SUCCESS) {
00793                 switch_channel_event_set_data(channel, event);
00794                 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-File-Path", file);
00795                 switch_event_fire(&event);
00796         }
00797 
00798         switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
00799         return status;
00800 }

static int teletone_handler ( teletone_generation_session_t ts,
teletone_tone_map_t map 
) [static]

Definition at line 802 of file switch_ivr_play_say.c.

References teletone_generation_session::buffer, switch_buffer_write(), teletone_mux_tones(), and teletone_generation_session::user_data.

00803 {
00804         switch_buffer_t *audio_buffer = ts->user_data;
00805         int wrote;
00806 
00807         if (!audio_buffer) {
00808                 return -1;
00809         }
00810 
00811         wrote = teletone_mux_tones(ts, map);
00812         switch_buffer_write(audio_buffer, ts->buffer, wrote * 2);
00813 
00814         return 0;
00815 }


Generated on Sun May 20 04:00:11 2012 for FreeSWITCH API Documentation by  doxygen 1.4.7