FreeSWITCH API Documentation  1.7.0
Data Structures | Macros | Typedefs | Functions
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
 

Macros

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

Typedefs

typedef struct 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)
 
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 More...
 
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. More...
 
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. More...
 
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)
 

Macro Definition Documentation

#define FILE_BLOCKSIZE   1024 * 8

Definition at line 1150 of file switch_ivr_play_say.c.

Referenced by switch_ivr_play_file().

#define FILE_BUFSIZE   1024 * 64

Definition at line 1151 of file switch_ivr_play_say.c.

Referenced by switch_ivr_play_file().

#define FILE_STARTSAMPLES   1024 * 32

Definition at line 1149 of file switch_ivr_play_say.c.

Referenced by switch_ivr_play_file().

Typedef Documentation

Definition at line 2627 of file switch_ivr_play_say.c.

Function Documentation

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 2799 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().

2800 {
2801  char *stop_key = (char *) buf;
2802 
2803  switch (itype) {
2805  {
2806  switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
2807  if (dtmf->digit == *stop_key) {
2808  return SWITCH_STATUS_BREAK;
2809  }
2810  }
2811  break;
2812  default:
2813  break;
2814  }
2815 
2816  return SWITCH_STATUS_SUCCESS;
2817 }
switch_byte_t switch_byte_t * buf
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, arg_recursion_check_start, arg_recursion_check_stop, switch_frame::buflen, CF_BREAK, CF_VIDEO, CF_VIDEO_BLANK, CF_VIDEO_DECODED_READ, CF_VIDEO_ECHO, switch_file_handle::channels, switch_frame::codec, switch_frame::data, switch_stream_handle::data, switch_frame::datalen, switch_codec_implementation::decoded_bytes_per_packet, switch_dtmf_t::digit, switch_codec_implementation::encoded_bytes_per_packet, switch_vid_params_s::fps, switch_vid_params_s::height, switch_codec_implementation::iananame, if(), switch_codec::implementation, memset(), switch_codec_implementation::microseconds_per_packet, switch_codec_implementation::number_of_channels, switch_frame::samples, switch_codec_implementation::samples_per_packet, SCFC_FLUSH_AUDIO, 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_clear_flag(), switch_channel_clear_flag_recursive(), switch_channel_dequeue_dtmf(), switch_channel_event_set_data(), switch_channel_expand_variables, switch_channel_get_name(), switch_channel_get_variable, switch_channel_hangup, switch_channel_has_dtmf(), switch_channel_media_ready, switch_channel_pre_answer, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag, switch_channel_set_flag_recursive(), switch_channel_set_variable, switch_channel_set_variable_printf(), switch_channel_test_flag(), switch_clear_flag_locked, SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, switch_core_codec_destroy(), switch_core_codec_init, switch_core_file_close(), switch_core_file_command(), switch_core_file_has_video(), switch_core_file_open, switch_core_file_read(), switch_core_file_seek(), switch_core_file_set_string(), switch_core_file_write(), switch_core_media_gen_key_frame, switch_core_media_get_vid_params(), switch_core_media_lock_video_file(), switch_core_media_set_video_file(), switch_core_media_unlock_video_file(), 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_request_video_refresh(), switch_core_session_reset(), switch_core_session_set_read_codec(), switch_core_session_sprintf(), switch_core_session_strdup, switch_core_session_wait_for_video_input_params(), 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_get_header, SWITCH_EVENT_RECORD_START, SWITCH_EVENT_RECORD_STOP, SWITCH_FALSE, SWITCH_FILE_DATA_SHORT, SWITCH_FILE_FLAG_READ, SWITCH_FILE_FLAG_VIDEO, SWITCH_FILE_FLAG_VIDEO_EOF, SWITCH_FILE_FLAG_WRITE, SWITCH_FILE_NATIVE, SWITCH_FILE_OPEN, 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_RW_READ, SWITCH_RW_WRITE, 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, switch_frame::user_data, switch_vid_params_s::width, and write_buf().

358 {
360  switch_dtmf_t dtmf = { 0 };
361  switch_file_handle_t lfh = { 0 };
362  switch_file_handle_t vfh = { 0 };
363  switch_file_handle_t ind_fh = { 0 };
364  switch_frame_t *read_frame;
365  switch_codec_t codec, write_codec = { 0 };
366  char *codec_name;
368  const char *p;
369  const char *vval;
370  time_t start = 0;
371  uint32_t org_silence_hits = 0;
372  int asis = 0;
373  int32_t sample_start = 0;
374  int waste_resources = 1400, fill_cng = 0;
375  switch_codec_implementation_t read_impl = { 0 };
376  switch_frame_t write_frame = { 0 };
377  unsigned char write_buf[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 };
378  switch_event_t *event;
379  int divisor = 0;
381  int restart_limit_on_dtmf = 0;
382  const char *prefix, *var, *video_file = NULL;
384  int echo_on = 0;
385 
387  return SWITCH_STATUS_FALSE;
388  }
389 
390  prefix = switch_channel_get_variable(channel, "sound_prefix");
391 
392  if (!prefix) {
394  }
395 
396  if (!switch_channel_media_ready(channel)) {
397  return SWITCH_STATUS_FALSE;
398  }
399 
400  switch_core_session_get_read_impl(session, &read_impl);
401 
402  if (!(divisor = read_impl.actual_samples_per_second / 8000)) {
403  divisor = 1;
404  }
405 
407 
408  if (!fh) {
409  fh = &lfh;
410  }
411 
412  fh->channels = read_impl.number_of_channels;
413  fh->native_rate = read_impl.actual_samples_per_second;
414 
415  if (fh->samples > 0) {
416  sample_start = fh->samples;
417  fh->samples = 0;
418  }
419 
420 
421  if ((p = switch_channel_get_variable(channel, "record_sample_rate"))) {
422  int tmp = 0;
423 
424  tmp = atoi(p);
425 
426  if (switch_is_valid_rate(tmp)) {
427  fh->samplerate = tmp;
428  }
429  }
430 
431  if (!strstr(file, SWITCH_URL_SEPARATOR)) {
432  char *ext;
433 
434  if (!switch_is_file_path(file)) {
435  char *tfile = NULL;
436  char *e;
437 
438  if (*file == '{') {
439  tfile = switch_core_session_strdup(session, file);
440 
441  while (*file == '{') {
442  if ((e = switch_find_end_paren(tfile, '{', '}'))) {
443  *e = '\0';
444  file = e + 1;
445  while(*file == ' ') file++;
446  } else {
447  tfile = NULL;
448  break;
449  }
450  }
451  }
452 
453  file = switch_core_session_sprintf(session, "%s%s%s%s%s", switch_str_nil(tfile), tfile ? "}" : "", prefix, SWITCH_PATH_SEPARATOR, file);
454  }
455  if ((ext = strrchr(file, '.'))) {
456  ext++;
457  } else {
458  ext = read_impl.iananame;
459  file = switch_core_session_sprintf(session, "%s.%s", file, ext);
460  asis = 1;
461  }
462  }
463 
464  if (asis && read_impl.encoded_bytes_per_packet == 0) {
465  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s cannot play or record native files with variable length data\n", switch_channel_get_name(channel));
468  return SWITCH_STATUS_GENERR;
469  }
470 
471 
472  vval = switch_channel_get_variable(channel, "enable_file_write_buffering");
473  if (!vval || switch_true(vval)) {
475  }
476 
477  if (switch_test_flag(fh, SWITCH_FILE_WRITE_APPEND) || ((p = switch_channel_get_variable(channel, "RECORD_APPEND")) && switch_true(p))) {
478  file_flags |= SWITCH_FILE_WRITE_APPEND;
479  }
480 
481  if (switch_test_flag(fh, SWITCH_FILE_WRITE_OVER) || ((p = switch_channel_get_variable(channel, "RECORD_WRITE_OVER")) && switch_true(p))) {
482  file_flags |= SWITCH_FILE_WRITE_OVER;
483  }
484 
485  if (!fh->prefix) {
486  fh->prefix = prefix;
487  }
488 
489  if (switch_channel_test_flag(channel, CF_VIDEO)) {
490  switch_vid_params_t vid_params = { 0 };
491 
492  file_flags |= SWITCH_FILE_FLAG_VIDEO;
496  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unable to establish inbound video stream\n");
499  return SWITCH_STATUS_GENERR;
500  }
501  switch_core_media_get_vid_params(session, &vid_params);
502  fh->mm.vw = vid_params.width;
503  fh->mm.vh = vid_params.height;
504  fh->mm.fps = vid_params.fps;
505  }
506 
507  if (switch_core_file_open(fh, file, fh->channels, read_impl.actual_samples_per_second, file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
511  return SWITCH_STATUS_GENERR;
512  }
513 
514 
515  if ((p = switch_channel_get_variable(channel, "record_fill_cng")) || (fh->params && (p = switch_event_get_header(fh->params, "record_fill_cng")))) {
516  if (!strcasecmp(p, "true")) {
517  fill_cng = 1400;
518  } else {
519  if ((fill_cng = atoi(p)) < 0) {
520  fill_cng = 0;
521  }
522  }
523  }
524 
525  if ((p = switch_channel_get_variable(channel, "record_indication")) || (fh->params && (p = switch_event_get_header(fh->params, "record_indication")))) {
527  waste_resources = 1400;
528 
529  if (switch_core_file_open(&ind_fh,
530  p,
531  read_impl.number_of_channels,
532  read_impl.actual_samples_per_second, flags, NULL) != SWITCH_STATUS_SUCCESS) {
533  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Indication file invalid\n");
534  }
535  }
536 
537  if ((p = switch_channel_get_variable(channel, "record_waste_resources")) ||
538  (fh->params && (p = switch_event_get_header(fh->params, "record_waste_resources")))) {
539 
540  if (!strcasecmp(p, "true")) {
541  waste_resources = 1400;
542  } else {
543  if ((waste_resources = atoi(p)) < 0) {
544  waste_resources = 0;
545  }
546  }
547  }
548 
549  if (fill_cng || waste_resources) {
550  if (switch_core_codec_init(&write_codec,
551  "L16",
552  NULL,
553  NULL,
554  read_impl.actual_samples_per_second,
555  read_impl.microseconds_per_packet / 1000,
556  read_impl.number_of_channels,
559  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activated, ready to waste resources!\n");
560  write_frame.data = write_buf;
561  write_frame.buflen = sizeof(write_buf);
562  write_frame.datalen = read_impl.decoded_bytes_per_packet;
563  write_frame.samples = write_frame.datalen / 2;
564  write_frame.codec = &write_codec;
565  } else {
567  return SWITCH_STATUS_FALSE;
568  }
569  }
570 
571 
572 
575 
576  if ((p = switch_channel_get_variable(channel, "record_play_video")) ||
577 
578  (fh->params && (p = switch_event_get_header(fh->params, "record_play_video")))) {
579 
580  video_file = switch_core_session_strdup(session, p);
581 
582  if (switch_core_file_open(&vfh, video_file, fh->channels,
583  read_impl.actual_samples_per_second, vid_play_file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
584  memset(&vfh, 0, sizeof(vfh));
585  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failure opening video playback file.\n");
586  }
587 
591  } else {
593  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Video playback file does not contain video\n");
594  memset(&vfh, 0, sizeof(vfh));
595  }
596  }
597 
598  if (!switch_test_flag(&vfh, SWITCH_FILE_OPEN)) {
599  echo_on = 1;
602  }
603 
605  } else if (switch_channel_test_flag(channel, CF_VIDEO)) {
607  }
608 
609  if (sample_start > 0) {
610  uint32_t pos = 0;
611  switch_core_file_seek(fh, &pos, sample_start, SEEK_SET);
613  fh->samples = 0;
614  }
615 
616 
618  asis = 1;
619  }
620 
621  restart_limit_on_dtmf = switch_true(switch_channel_get_variable(channel, "record_restart_limit_on_dtmf"));
622 
623  if ((p = switch_channel_get_variable(channel, "record_title")) || (fh->params && (p = switch_event_get_header(fh->params, "record_title")))) {
624  vval = switch_core_session_strdup(session, p);
626  switch_channel_set_variable(channel, "record_title", NULL);
627  }
628 
629  if ((p = switch_channel_get_variable(channel, "record_copyright")) || (fh->params && (p = switch_event_get_header(fh->params, "record_copyright")))) {
630  vval = switch_core_session_strdup(session, p);
632  switch_channel_set_variable(channel, "record_copyright", NULL);
633  }
634 
635  if ((p = switch_channel_get_variable(channel, "record_software")) || (fh->params && (p = switch_event_get_header(fh->params, "record_software")))) {
636  vval = switch_core_session_strdup(session, p);
638  switch_channel_set_variable(channel, "record_software", NULL);
639  }
640 
641  if ((p = switch_channel_get_variable(channel, "record_artist")) || (fh->params && (p = switch_event_get_header(fh->params, "record_artist")))) {
642  vval = switch_core_session_strdup(session, p);
644  switch_channel_set_variable(channel, "record_artist", NULL);
645  }
646 
647  if ((p = switch_channel_get_variable(channel, "record_comment")) || (fh->params && (p = switch_event_get_header(fh->params, "record_comment")))) {
648  vval = switch_core_session_strdup(session, p);
650  switch_channel_set_variable(channel, "record_comment", NULL);
651  }
652 
653  if ((p = switch_channel_get_variable(channel, "record_date")) || (fh->params && (p = switch_event_get_header(fh->params, "record_date")))) {
654  vval = switch_core_session_strdup(session, p);
656  switch_channel_set_variable(channel, "record_date", NULL);
657  }
658 
659 
660  switch_channel_set_variable(channel, "silence_hits_exhausted", "false");
661 
662  if (!asis) {
663  codec_name = "L16";
664  if (switch_core_codec_init(&codec,
665  codec_name,
666  NULL,
667  NULL,
668  read_impl.actual_samples_per_second,
669  read_impl.microseconds_per_packet / 1000,
670  read_impl.number_of_channels,
673  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activated\n");
674  switch_core_session_set_read_codec(session, &codec);
675  } else {
677  "Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate,
678  fh->channels, read_impl.microseconds_per_packet / 1000);
680  if (echo_on) {
683  echo_on = 0;
684  }
687  }
690 
693  return SWITCH_STATUS_GENERR;
694  }
695  }
696 
697  if (limit) {
698  start = switch_epoch_time_now(NULL);
699  }
700 
701  if (fh->thresh) {
702  if (asis) {
703  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Can't detect silence on a native recording.\n");
704  } else {
705  if (fh->silence_hits) {
706  fh->silence_hits = fh->samplerate * fh->silence_hits / read_impl.samples_per_packet;
707  } else {
708  fh->silence_hits = fh->samplerate * 3 / read_impl.samples_per_packet;
709  }
710  org_silence_hits = fh->silence_hits;
711  }
712  }
713 
714 
716  switch_channel_event_set_data(channel, event);
717  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-File-Path", file);
718  switch_event_fire(&event);
719  }
720 
721  for (;;) {
722  switch_size_t len;
723 
724  if (!switch_channel_ready(channel)) {
725  status = SWITCH_STATUS_FALSE;
726  break;
727  }
728 
729  if (switch_channel_test_flag(channel, CF_BREAK)) {
731  status = SWITCH_STATUS_BREAK;
732  break;
733  }
734 
736 
737  if (start && (switch_epoch_time_now(NULL) - start) > limit) {
738  break;
739  }
740 
741  if (args) {
742  /*
743  dtmf handler function you can hook up to be executed when a digit is dialed during playback
744  if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
745  */
746  if (switch_channel_has_dtmf(channel)) {
747 
748  if (limit && restart_limit_on_dtmf) {
749  start = switch_epoch_time_now(NULL);
750  }
751 
752  if (!args->input_callback && !args->buf && !args->dmachine) {
753  status = SWITCH_STATUS_BREAK;
754  break;
755  }
756  switch_channel_dequeue_dtmf(channel, &dtmf);
757 
758  if (args->dmachine) {
759  char ds[2] = {dtmf.digit, '\0'};
760  if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
761  break;
762  }
763  }
764 
765  if (args->input_callback) {
766  status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
767  } else if (args->buf) {
768  *((char *) args->buf) = dtmf.digit;
769  status = SWITCH_STATUS_BREAK;
770  }
771  }
772 
773  if (args->input_callback) {
774  switch_event_t *event = NULL;
775  switch_status_t ostatus;
776 
778  if ((ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen)) != SWITCH_STATUS_SUCCESS) {
779  status = ostatus;
780  }
781 
782  switch_event_destroy(&event);
783  }
784  }
785 
786  if (status != SWITCH_STATUS_SUCCESS) {
787  break;
788  }
789  }
790 
791  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
792  if (!SWITCH_READ_ACCEPTABLE(status)) {
793  break;
794  }
795 
796  if (args && args->dmachine) {
797  if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
798  break;
799  }
800  }
801 
802  if (args && (args->read_frame_callback)) {
803  if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
804  break;
805  }
806  }
807 
808  if (switch_test_flag(&vfh, SWITCH_FILE_OPEN)) {
810 
812 
813  //switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
814 
816 
818  memset(&vfh, 0, sizeof(vfh));
819 
820  if (switch_core_file_open(&vfh, video_file, fh->channels,
821  read_impl.actual_samples_per_second, vid_play_file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
822  memset(&vfh, 0, sizeof(vfh));
823  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failure opening video playback file.\n");
824  }
825 
827  //switch_core_media_set_video_file(session, &vfh, SWITCH_RW_WRITE);
829  } else {
832  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Video playback file does not contain video\n");
833  memset(&vfh, 0, sizeof(vfh));
834  }
835 
837  }
838 
839  }
840 
841  if (!asis && fh->thresh) {
842  int16_t *fdata = (int16_t *) read_frame->data;
843  uint32_t samples = read_frame->datalen / sizeof(*fdata);
844  uint32_t score, count = 0, j = 0;
845  double energy = 0;
846 
847 
848  for (count = 0; count < samples * read_impl.number_of_channels; count++) {
849  energy += abs(fdata[j++]);
850  }
851 
852  score = (uint32_t) (energy / (samples / divisor));
853 
854  if (score < fh->thresh) {
855  if (!--fh->silence_hits) {
856  switch_channel_set_variable(channel, "silence_hits_exhausted", "true");
857  break;
858  }
859  } else {
860  fh->silence_hits = org_silence_hits;
861  }
862  }
863 
864  write_frame.datalen = read_impl.decoded_bytes_per_packet;
865  write_frame.samples = write_frame.datalen / 2;
866 
867  if (switch_test_flag(&ind_fh, SWITCH_FILE_OPEN)) {
869 
870  if (switch_core_file_read(&ind_fh, write_frame.data, &olen) == SWITCH_STATUS_SUCCESS) {
871  write_frame.samples = olen;
872  write_frame.datalen = olen * 2 * ind_fh.channels;;
873  } else {
874  switch_core_file_close(&ind_fh);
875  }
876 
877  } else if (fill_cng) {
878  switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, read_impl.number_of_channels, fill_cng);
879  } else if (waste_resources) {
880  switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, read_impl.number_of_channels, waste_resources);
881  }
882 
883  if (!switch_test_flag(fh, SWITCH_FILE_PAUSE) && !switch_test_flag(read_frame, SFF_CNG)) {
884  int16_t *data = read_frame->data;
885  len = (switch_size_t) asis ? read_frame->datalen : read_frame->datalen / 2 / fh->channels;
886 
887  if (switch_core_file_write(fh, data, &len) != SWITCH_STATUS_SUCCESS) {
888  break;
889  }
890  } else if (switch_test_flag(read_frame, SFF_CNG) && fill_cng) {
891  len = write_frame.datalen / 2 / fh->channels;
892  if (switch_core_file_write(fh, write_frame.data, &len) != SWITCH_STATUS_SUCCESS) {
893  break;
894  }
895  }
896 
897 
898  if (waste_resources || switch_test_flag(&ind_fh, SWITCH_FILE_OPEN)) {
900  break;
901  }
902  }
903  }
904 
905  if (fill_cng || waste_resources) {
906  switch_core_codec_destroy(&write_codec);
907  }
908 
910  if (echo_on) {
913  echo_on = 0;
914  }
917  }
920 
921 
922  if ((var = switch_channel_get_variable(channel, "record_post_process_exec_api"))) {
923  char *cmd = switch_core_session_strdup(session, var);
924  char *data, *expanded = NULL;
925  switch_stream_handle_t stream = { 0 };
926 
927  SWITCH_STANDARD_STREAM(stream);
928 
929  if ((data = strchr(cmd, ':'))) {
930  *data++ = '\0';
931  expanded = switch_channel_expand_variables(channel, data);
932  }
933 
934  switch_api_execute(cmd, expanded, session, &stream);
935 
936  if (expanded && expanded != data) {
937  free(expanded);
938  }
939 
940  switch_safe_free(stream.data);
941 
942  }
943 
944  if (read_impl.actual_samples_per_second) {
945  switch_channel_set_variable_printf(channel, "record_seconds", "%d", fh->samples_out / fh->native_rate);
946  switch_channel_set_variable_printf(channel, "record_ms", "%d", fh->samples_out / (fh->native_rate/ 1000));
947 
948  }
949 
950  switch_channel_set_variable_printf(channel, "record_samples", "%d", fh->samples_out);
951 
953  switch_channel_event_set_data(channel, event);
954  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-File-Path", file);
955  switch_event_fire(&event);
956  }
957 
959 
961  return status;
962 }
switch_status_t switch_channel_set_variable_printf(switch_channel_t *channel, const char *varname, const char *fmt,...)
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:412
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it's state machine to end.
#define switch_core_media_gen_key_frame(_session)
void switch_channel_set_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
char * switch_core_session_sprintf(_In_ switch_core_session_t *session, _In_z_ _Printf_format_string_ const char *fmt,...)
printf-style style printing routine. The data is output to a string allocated from the session ...
#define SWITCH_CHANNEL_SESSION_LOG(x)
void switch_core_session_reset(_In_ switch_core_session_t *session, switch_bool_t flush_dtmf, switch_bool_t reset_read_codec)
Reset the buffers and resampler on a session.
switch_status_t switch_ivr_dmachine_feed(switch_ivr_dmachine_t *dmachine, const char *digits, switch_ivr_dmachine_match_t **match)
char * switch_find_end_paren(const char *s, char open, char close)
Definition: switch_utils.c:661
#define switch_core_file_open(_fh, _file_path, _channels, _rate, _flags, _pool)
Open a media file using file format modules.
Definition: switch_core.h:1865
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:557
void switch_channel_event_set_data(_In_ switch_channel_t *channel, _In_ switch_event_t *event)
Add information about a given channel to an event object.
switch_status_t switch_core_session_set_read_codec(_In_ switch_core_session_t *session, switch_codec_t *codec)
Assign the read codec to a given session.
#define SWITCH_URL_SEPARATOR
Definition: switch_types.h:124
switch_status_t switch_core_file_command(switch_file_handle_t *fh, switch_file_command_t command)
switch_status_t switch_core_file_set_string(_In_ switch_file_handle_t *fh, switch_audio_col_t col, const char *string)
Set metadata to the desired string.
switch_status_t switch_api_execute(const char *cmd, const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream)
Execute a registered API command.
Representation of an event.
Definition: switch_event.h:80
switch_status_t switch_core_file_close(_In_ switch_file_handle_t *fh)
Close an open file handle.
#define switch_channel_ready(_channel)
#define arg_recursion_check_stop(_args)
switch_status_t switch_core_media_set_video_file(switch_core_session_t *session, switch_file_handle_t *fh, switch_rw_t rw)
void switch_generate_sln_silence(int16_t *data, uint32_t samples, uint32_t channels, uint32_t divisor)
Generate static noise.
#define switch_channel_media_ready(_channel)
switch_status_t switch_core_file_seek(_In_ switch_file_handle_t *fh, unsigned int *cur_pos, int64_t samples, int whence)
Seek a position in a file.
switch_status_t switch_core_codec_destroy(switch_codec_t *codec)
Destroy an initalized codec handle.
switch_status_t switch_core_file_read(_In_ switch_file_handle_t *fh, void *data, switch_size_t *len)
Read media from a file handle.
switch_status_t switch_ivr_parse_all_events(switch_core_session_t *session)
Parse all commands from an event.
Definition: switch_ivr.c:867
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
switch_status_t switch_core_session_read_frame(_In_ switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
Read a frame from a session.
switch_codec_t * codec
Definition: switch_frame.h:45
switch_status_t switch_core_session_write_frame(_In_ switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
Write a frame to a session.
switch_status_t switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:122
const switch_codec_implementation_t * implementation
uint32_t buflen
Definition: switch_frame.h:59
if((uint32_t)(unpack->cur-unpack->buf) > unpack->buflen)
uint32_t datalen
Definition: switch_frame.h:57
#define switch_channel_get_variable(_c, _v)
switch_status_t switch_channel_dequeue_dtmf(_In_ switch_channel_t *channel, _In_ switch_dtmf_t *dtmf)
Retrieve DTMF digits from a given channel.
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
switch_input_callback_function_t input_callback
An abstraction of a data frame.
Definition: switch_frame.h:43
uintptr_t switch_size_t
#define arg_recursion_check_start(_args)
#define switch_core_codec_init(_codec, _codec_name, _modname, _fmtp, _rate, _ms, _channels, _flags, _codec_settings, _pool)
Initialize a codec handle.
Definition: switch_core.h:1602
#define SWITCH_STANDARD_STREAM(s)
switch_status_t switch_core_session_wait_for_video_input_params(switch_core_session_t *session, uint32_t timeout_ms)
switch_directories SWITCH_GLOBAL_dirs
Definition: switch_core.c:60
switch_read_frame_callback_function_t read_frame_callback
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:903
switch_status_t switch_core_media_get_vid_params(switch_core_session_t *session, switch_vid_params_t *vid_params)
#define switch_channel_expand_variables(_channel, _in)
switch_status_t switch_core_session_request_video_refresh(switch_core_session_t *session)
#define switch_clear_flag_locked(obj, flag)
Clear a flag on an arbitrary object.
Definition: switch_utils.h:648
switch_status_t
Common return values.
switch_status_t switch_core_file_write(_In_ switch_file_handle_t *fh, void *data, switch_size_t *len)
Write media to a file handle.
switch_status_t switch_core_session_dequeue_event(_In_ switch_core_session_t *session, _Out_ switch_event_t **event, switch_bool_t force)
DE-Queue an event on a given session.
switch_size_t switch_channel_has_dtmf(_In_ switch_channel_t *channel)
Test for presence of DTMF on a given channel.
static int write_buf(int fd, const char *buf)
Definition: switch_utils.c:969
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:383
static switch_bool_t switch_is_file_path(const char *file)
uint32_t samples
Definition: switch_frame.h:61
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172
#define switch_channel_set_flag(_c, _f)
switch_bool_t switch_core_file_has_video(switch_file_handle_t *fh, switch_bool_t CHECK_OPEN)
switch_status_t switch_core_media_unlock_video_file(switch_core_session_t *session, switch_rw_t rw)
switch_status_t switch_ivr_dmachine_ping(switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_match_t **match_p)
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:321
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_channel_clear_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
A table of settings and callbacks that define a paticular implementation of a codec.
#define switch_is_valid_rate(_tmp)
Definition: switch_utils.h:344
switch_status_t switch_core_media_lock_video_file(switch_core_session_t *session, switch_rw_t rw)
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
void switch_event_destroy(switch_event_t **event)
Destroy an event.
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
#define switch_channel_set_variable(_channel, _var, _val)
#define switch_channel_pre_answer(channel)
Indicate progress on a channel to attempt early media.
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
#define SWITCH_READ_ACCEPTABLE(status)
Definition: switch_utils.h:995
memset(buf, 0, buflen)
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
#define SWITCH_DEFAULT_FILE_BUFFER_LEN
Definition: switch_types.h:229
switch_ivr_dmachine_t * dmachine
static int teletone_handler ( teletone_generation_session_t ts,
teletone_tone_map_t map 
)
static

Definition at line 964 of file switch_ivr_play_say.c.

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

Referenced by switch_ivr_gentones().

965 {
966  switch_buffer_t *audio_buffer = ts->user_data;
967  int wrote;
968 
969  if (!audio_buffer) {
970  return -1;
971  }
972 
973  wrote = teletone_mux_tones(ts, map);
974  switch_buffer_write(audio_buffer, ts->buffer, wrote * 2);
975 
976  return 0;
977 }
int teletone_mux_tones(teletone_generation_session_t *ts, teletone_tone_map_t *map)
Execute a single tone generation instruction.
switch_size_t switch_buffer_write(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ switch_size_t datalen)
Write data into a switch_buffer_t up to the length of datalen.