Main Page | Modules | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

switch_ivr_play_say.c File Reference


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_say_method_t switch_ivr_get_say_method_by_name (const char *name)
switch_say_type_t switch_ivr_get_say_type_by_name (const char *name)
switch_status_t switch_ivr_phrase_macro (switch_core_session_t *session, const char *macro_name, const char *data, 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)
switch_status_t switch_ivr_gentones (switch_core_session_t *session, char *script, int32_t loops, switch_input_args_t *args)
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_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)
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, char *valid_terminators, char *prompt_audio_file, char *bad_input_audio_file, void *digit_buffer, uint32_t digit_buffer_length, char *digits_regex)
 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.
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
 

#define FILE_BUFSIZE   1024 * 64
 

#define FILE_STARTSAMPLES   1024 * 32
 


Typedef Documentation

typedef struct cached_speech_handle cached_speech_handle_t
 


Function Documentation

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
 

00361 {
00362         switch_channel_t *channel = switch_core_session_get_channel(session);
00363         switch_dtmf_t dtmf = {0};
00364         switch_file_handle_t lfh = { 0 };
00365         switch_frame_t *read_frame;
00366         switch_codec_t codec, *read_codec = switch_core_session_get_read_codec(session);
00367         char *codec_name;
00368         switch_status_t status = SWITCH_STATUS_SUCCESS;
00369         const char *p;
00370         const char *vval;
00371         time_t start = 0;
00372         uint32_t org_silence_hits = 0;
00373 
00374         switch_assert(read_codec != NULL);
00375 
00376         if (!fh) {
00377                 fh = &lfh;
00378         }
00379 
00380         switch_channel_pre_answer(channel);
00381 
00382         fh->channels = read_codec->implementation->number_of_channels;
00383         fh->native_rate = read_codec->implementation->actual_samples_per_second;
00384 
00385         if (switch_core_file_open(fh,
00386                                                           file,
00387                                                           fh->channels,
00388                                                           read_codec->implementation->actual_samples_per_second,
00389                                                           SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
00390                 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
00391                 switch_core_session_reset(session, SWITCH_TRUE);
00392                 return SWITCH_STATUS_GENERR;
00393         }
00394 
00395         switch_channel_pre_answer(channel);
00396 
00397         if ((p = switch_channel_get_variable(channel, "RECORD_TITLE"))) {
00398                 vval = switch_core_session_strdup(session, p);
00399                 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_TITLE, vval);
00400                 switch_channel_set_variable(channel, "RECORD_TITLE", NULL);
00401         }
00402 
00403         if ((p = switch_channel_get_variable(channel, "RECORD_COPYRIGHT"))) {
00404                 vval = switch_core_session_strdup(session, p);
00405                 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COPYRIGHT, vval);
00406                 switch_channel_set_variable(channel, "RECORD_COPYRIGHT", NULL);
00407         }
00408 
00409         if ((p = switch_channel_get_variable(channel, "RECORD_SOFTWARE"))) {
00410                 vval = switch_core_session_strdup(session, p);
00411                 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_SOFTWARE, vval);
00412                 switch_channel_set_variable(channel, "RECORD_SOFTWARE", NULL);
00413         }
00414 
00415         if ((p = switch_channel_get_variable(channel, "RECORD_ARTIST"))) {
00416                 vval = switch_core_session_strdup(session, p);
00417                 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_ARTIST, vval);
00418                 switch_channel_set_variable(channel, "RECORD_ARTIST", NULL);
00419         }
00420 
00421         if ((p = switch_channel_get_variable(channel, "RECORD_COMMENT"))) {
00422                 vval = switch_core_session_strdup(session, p);
00423                 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COMMENT, vval);
00424                 switch_channel_set_variable(channel, "RECORD_COMMENT", NULL);
00425         }
00426 
00427         if ((p = switch_channel_get_variable(channel, "RECORD_DATE"))) {
00428                 vval = switch_core_session_strdup(session, p);
00429                 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_DATE, vval);
00430                 switch_channel_set_variable(channel, "RECORD_DATE", NULL);
00431         }
00432 
00433         codec_name = "L16";
00434         if (switch_core_codec_init(&codec,
00435                                                            codec_name,
00436                                                            NULL,
00437                                                            read_codec->implementation->actual_samples_per_second,
00438                                                            read_codec->implementation->microseconds_per_frame / 1000,
00439                                                            read_codec->implementation->number_of_channels,
00440                                                            SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
00441                                                            switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
00442                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activated\n");
00443                 switch_core_session_set_read_codec(session, &codec);
00444         } else {
00445                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
00446                                                   "Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate,
00447                                                   fh->channels, read_codec->implementation->microseconds_per_frame / 1000);
00448                 switch_core_file_close(fh);
00449                 switch_core_session_reset(session, SWITCH_TRUE);
00450                 return SWITCH_STATUS_GENERR;
00451         }
00452 
00453         if (limit) {
00454                 start = switch_timestamp(NULL);
00455         }
00456 
00457         if (fh->thresh) {
00458                 if (fh->silence_hits) {
00459                         fh->silence_hits = fh->samplerate * fh->silence_hits / read_codec->implementation->samples_per_frame;
00460                 } else {
00461                         fh->silence_hits = fh->samplerate * 3 / read_codec->implementation->samples_per_frame;
00462                 }
00463                 org_silence_hits = fh->silence_hits;
00464         }
00465 
00466         for(;;) {
00467                 switch_size_t len;
00468                 
00469                 if (!switch_channel_ready(channel)) {
00470                         status = SWITCH_STATUS_FALSE;
00471                         break;
00472                 }
00473 
00474                 if (switch_channel_test_flag(channel, CF_BREAK)) {
00475                         switch_channel_clear_flag(channel, CF_BREAK);
00476                         status = SWITCH_STATUS_BREAK;
00477                         break;
00478                 }
00479                 
00480                 if (switch_core_session_private_event_count(session)) {
00481                         switch_ivr_parse_all_events(session);
00482                 }
00483 
00484                 if (start && (switch_timestamp(NULL) - start) > limit) {
00485                         break;
00486                 }
00487 
00488                 if (args && (args->input_callback || args->buf || args->buflen)) {
00489                         /*
00490                            dtmf handler function you can hook up to be executed when a digit is dialed during playback 
00491                            if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
00492                          */
00493                         if (switch_channel_has_dtmf(channel)) {
00494                                 if (!args->input_callback && !args->buf) {
00495                                         status = SWITCH_STATUS_BREAK;
00496                                         break;
00497                                 }
00498                                 switch_channel_dequeue_dtmf(channel, &dtmf);
00499                                 if (args->input_callback) {
00500                                         status = args->input_callback(session, (void *)&dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
00501                                 } else {
00502                                         switch_copy_string((char *) args->buf, (void *)&dtmf, args->buflen);
00503                                         status = SWITCH_STATUS_BREAK;
00504                                 }
00505                         }
00506 
00507                         if (args->input_callback) {
00508                                 switch_event_t *event = NULL;
00509 
00510                                 if (switch_core_session_dequeue_event(session, &event) == SWITCH_STATUS_SUCCESS) {
00511                                         status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
00512                                         switch_event_destroy(&event);
00513                                 }
00514                         }
00515 
00516                         if (status != SWITCH_STATUS_SUCCESS) {
00517                                 break;
00518                         }
00519                 }
00520 
00521                 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
00522                 if (!SWITCH_READ_ACCEPTABLE(status)) {
00523                         break;
00524                 }
00525 
00526                 if (args && (args->read_frame_callback)) {
00527                         if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
00528                                 break;
00529                         }
00530                 }
00531 
00532                 if (fh->thresh) {
00533                         int16_t *fdata = (int16_t *) read_frame->data;
00534                         uint32_t samples = read_frame->datalen / sizeof(*fdata);
00535                         uint32_t score, count = 0, j = 0;
00536                         double energy = 0;
00537                         int divisor = 0;
00538                         
00539                         for (count = 0; count < samples; count++) {
00540                                 energy += abs(fdata[j]);
00541                                 j += read_codec->implementation->number_of_channels;
00542                         }
00543 
00544                         if (!(divisor = read_codec->implementation->actual_samples_per_second / 8000)) {
00545                                 divisor = 1;
00546                         }
00547                         
00548                         score = (uint32_t) (energy / (samples / divisor));
00549                         if (score < fh->thresh) {
00550                                 if (!--fh->silence_hits) {
00551                                         break;
00552                                 }
00553                         } else {
00554                                 fh->silence_hits = org_silence_hits;
00555                         }
00556                 }
00557 
00558                 if (!switch_test_flag(fh, SWITCH_FILE_PAUSE) && !switch_test_flag(read_frame, SFF_CNG)) {
00559                         int16_t *data = read_frame->data;
00560                         len = (switch_size_t) read_frame->datalen / 2;
00561                         
00562                         if (switch_core_file_write(fh, data, &len) != SWITCH_STATUS_SUCCESS) {
00563                                 break;
00564                         }
00565                 }
00566         }
00567 
00568         switch_core_session_set_read_codec(session, read_codec);
00569         switch_core_file_close(fh);
00570         switch_core_session_reset(session, SWITCH_TRUE);
00571         return status;
00572 }

Here is the call graph for this function:


Generated on Mon May 26 22:06:52 2008 for FreeSWITCH by  doxygen 1.3.9.1