RTS API Documentation  1.10.11
Data Structures | Macros | Typedefs | Enumerations | 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
 
struct  switch_collect_input_state_t
 

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
 

Enumerations

enum  switch_collect_input_flags_t {
  SWITCH_COLLECT_INPUT_PROMPT = (1 << 0), SWITCH_COLLECT_INPUT_SPEECH = (1 << 1), SWITCH_COLLECT_INPUT_SPEECH_DONE = (1 << 2), SWITCH_COLLECT_INPUT_DIGITS = (1 << 3),
  SWITCH_COLLECT_INPUT_DIGITS_DONE = (1 << 4)
}
 

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)
 
static void merge_recording_variables (switch_event_t *vars, switch_event_t *event)
 
static const char * get_recording_var (switch_channel_t *channel, switch_event_t *vars, switch_file_handle_t *fh, const char *name)
 
static int recording_var_true (switch_channel_t *channel, switch_event_t *vars, switch_file_handle_t *fh, const char *name)
 
switch_status_t switch_ivr_record_file_event (switch_core_session_t *session, switch_file_handle_t *fh, const char *file, switch_input_args_t *args, uint32_t limit, switch_event_t *vars)
 
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_detect_audio (switch_core_session_t *session, uint32_t thresh, uint32_t audio_hits, uint32_t timeout_ms, const char *file)
 
switch_status_t switch_ivr_detect_silence (switch_core_session_t *session, uint32_t thresh, uint32_t silence_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, const 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, const 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)
 
static void deliver_asr_event (switch_core_session_t *session, switch_event_t *event, switch_input_args_t *args)
 
static switch_status_t switch_collect_input_callback (switch_core_session_t *session, void *input, switch_input_type_t input_type, void *data, unsigned int len)
 
switch_status_t switch_ivr_play_and_collect_input (switch_core_session_t *session, const char *prompt, const char *recognizer_mod_name, const char *recognizer_grammar, int min_digits, int max_digits, const char *terminators, uint32_t digit_timeout, cJSON **recognition_result, char **digits_collected, char *terminator_collected, switch_input_args_t *args)
 Play prompt and collect input. More...
 

Macro Definition Documentation

◆ FILE_BLOCKSIZE

#define FILE_BLOCKSIZE   1024 * 8

Definition at line 1241 of file switch_ivr_play_say.c.

Referenced by switch_ivr_play_file().

◆ FILE_BUFSIZE

#define FILE_BUFSIZE   1024 * 64

Definition at line 1242 of file switch_ivr_play_say.c.

Referenced by switch_ivr_play_file().

◆ FILE_STARTSAMPLES

#define FILE_STARTSAMPLES   1024 * 32

Definition at line 1240 of file switch_ivr_play_say.c.

Referenced by switch_ivr_play_file().

Typedef Documentation

◆ cached_speech_handle_t

Definition at line 3006 of file switch_ivr_play_say.c.

Enumeration Type Documentation

◆ switch_collect_input_flags_t

Enumerator
SWITCH_COLLECT_INPUT_PROMPT 

playing initial prompt - allow barge in

SWITCH_COLLECT_INPUT_SPEECH 

looking for speech input

SWITCH_COLLECT_INPUT_SPEECH_DONE 

finished looking for speech input

SWITCH_COLLECT_INPUT_DIGITS 

looking for digits

SWITCH_COLLECT_INPUT_DIGITS_DONE 

finished looking for digits

Definition at line 3263 of file switch_ivr_play_say.c.

3263  {
3264  /** playing initial prompt - allow barge in */
3265  SWITCH_COLLECT_INPUT_PROMPT = (1 << 0),
3266  /** looking for speech input */
3267  SWITCH_COLLECT_INPUT_SPEECH = (1 << 1),
3268  /** finished looking for speech input */
3270  /** looking for digits */
3271  SWITCH_COLLECT_INPUT_DIGITS = (1 << 3),
3272  /** finished looking for digits */
switch_collect_input_flags_t

Function Documentation

◆ deliver_asr_event()

static void deliver_asr_event ( switch_core_session_t session,
switch_event_t event,
switch_input_args_t args 
)
static

Definition at line 3289 of file switch_ivr_play_say.c.

References switch_input_args_t::buf, switch_input_args_t::buflen, switch_input_args_t::input_callback, and SWITCH_INPUT_TYPE_EVENT.

Referenced by switch_collect_input_callback().

3290 {
3291  if (args && args->input_callback) {
3292  args->input_callback(session, (void *)event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
3293  }
3294 }
switch_input_callback_function_t input_callback

◆ get_recording_var()

static const char* get_recording_var ( switch_channel_t channel,
switch_event_t vars,
switch_file_handle_t fh,
const char *  name 
)
static

Definition at line 384 of file switch_ivr_play_say.c.

References switch_file_handle::params, switch_channel_get_variable, and switch_event_get_header.

Referenced by recording_var_true(), and switch_ivr_record_file_event().

385 {
386  const char *val = NULL;
387  if (vars) {
388  val = switch_event_get_header(vars, name);
389  }
390  if (!val && fh && fh->params) {
391  val = switch_event_get_header(fh->params, name);
392  }
393  if (!val) {
394  val = switch_channel_get_variable(channel, name);
395  }
396  return val;
397 }
#define switch_channel_get_variable(_c, _v)
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172
const char *const name
Definition: switch_cJSON.h:250

◆ hold_on_dtmf()

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

3179 {
3180  char *stop_key = (char *) buf;
3181 
3182  switch (itype) {
3184  {
3185  switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
3186  if (dtmf->digit == *stop_key) {
3187  return SWITCH_STATUS_BREAK;
3188  }
3189  }
3190  break;
3191  default:
3192  break;
3193  }
3194 
3195  return SWITCH_STATUS_SUCCESS;
3196 }
switch_byte_t switch_byte_t * buf

◆ merge_recording_variables()

static void merge_recording_variables ( switch_event_t vars,
switch_event_t event 
)
static

Definition at line 366 of file switch_ivr_play_say.c.

References buf, switch_event::headers, switch_event_header::name, switch_event_header::next, switch_assert, switch_event_add_header_string(), switch_snprintf(), SWITCH_STACK_BOTTOM, and switch_event_header::value.

Referenced by switch_ivr_record_file_event().

367 {
369  if (vars) {
370  for (hi = vars->headers; hi; hi = hi->next) {
371  char buf[1024];
372  char *vvar = NULL, *vval = NULL;
373 
374  vvar = (char *) hi->name;
375  vval = (char *) hi->value;
376 
377  switch_assert(vvar && vval);
378  switch_snprintf(buf, sizeof(buf), "Recording-Variable-%s", vvar);
380  }
381  }
382 }
An event Header.
Definition: switch_event.h:65
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
switch_byte_t switch_byte_t * buf
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.
struct switch_event_header * next
Definition: switch_event.h:76
#define switch_assert(expr)
switch_event_header_t * headers
Definition: switch_event.h:90

◆ recording_var_true()

static int recording_var_true ( switch_channel_t channel,
switch_event_t vars,
switch_file_handle_t fh,
const char *  name 
)
static

Definition at line 399 of file switch_ivr_play_say.c.

References get_recording_var(), and switch_true().

Referenced by switch_ivr_record_file_event().

400 {
401  return switch_true(get_recording_var(channel, vars, fh, name));
402 }
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
static const char * get_recording_var(switch_channel_t *channel, switch_event_t *vars, switch_file_handle_t *fh, const char *name)
const char *const name
Definition: switch_cJSON.h:250

◆ switch_collect_input_callback()

static switch_status_t switch_collect_input_callback ( switch_core_session_t session,
void *  input,
switch_input_type_t  input_type,
void *  data,
unsigned int  len 
)
static

Definition at line 3296 of file switch_ivr_play_say.c.

References cJSON_GetObjectCstr(), deliver_asr_event(), switch_dtmf_t::digit, switch_collect_input_state_t::digits, switch_collect_input_state_t::is_speech, switch_collect_input_state_t::last_digit_time, switch_collect_input_state_t::max_digits, switch_collect_input_state_t::original_args, switch_collect_input_state_t::recognition_result, switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, SWITCH_COLLECT_INPUT_DIGITS, SWITCH_COLLECT_INPUT_DIGITS_DONE, SWITCH_COLLECT_INPUT_PROMPT, SWITCH_COLLECT_INPUT_SPEECH, SWITCH_COLLECT_INPUT_SPEECH_DONE, switch_core_session_get_channel(), SWITCH_EVENT_DETECTED_SPEECH, switch_event_get_body(), switch_event_get_header, SWITCH_FALSE, SWITCH_INPUT_TYPE_DTMF, SWITCH_INPUT_TYPE_EVENT, SWITCH_INT64_T_FMT, SWITCH_LOG_DEBUG, SWITCH_LOG_INFO, switch_log_printf(), switch_micro_time_now(), switch_set_flag, SWITCH_STATUS_BREAK, SWITCH_STATUS_SUCCESS, switch_test_flag, SWITCH_TRUE, switch_collect_input_state_t::terminator, switch_collect_input_state_t::terminators, and zstr.

Referenced by switch_ivr_play_and_collect_input().

3297 {
3300 
3302  const char *speech_type = NULL;
3303  switch_event_t *event = (switch_event_t *)input;
3304 
3305  if (event->event_id != SWITCH_EVENT_DETECTED_SPEECH) return SWITCH_STATUS_SUCCESS;
3306 
3307  speech_type = switch_event_get_header(event, "Speech-Type");
3308 
3309  if (zstr(speech_type)) return SWITCH_STATUS_SUCCESS;
3310 
3311  deliver_asr_event(session, event, state->original_args);
3312 
3313  if (!strcasecmp(speech_type, "detected-speech")) {
3314  const char *result = switch_event_get_body(event);
3315 
3316  /* stop waiting for speech */
3318 
3319  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "(%s) DETECTED SPEECH %s\n", switch_channel_get_name(channel), speech_type);
3320 
3321  if (!zstr(result)) {
3322  state->recognition_result = cJSON_Parse(result);
3323 
3324  if (state->recognition_result) {
3325  const char *text = cJSON_GetObjectCstr(state->recognition_result, "text");
3326 
3327  if (!zstr(text)) {
3328  /* stop waiting for digits */
3330  }
3331  }
3332  }
3333  return SWITCH_STATUS_BREAK;
3334  } else if (!strcasecmp(speech_type, "detected-partial-speech")) {
3335  } else if (!strcasecmp("closed", speech_type)) {
3336  /* stop waiting for speech */
3338  return SWITCH_STATUS_BREAK;
3339  } else if (!strcasecmp(speech_type, "begin-speaking")) {
3340  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "(%s) START OF SPEECH\n", switch_channel_get_name(channel));
3341  state->is_speech = SWITCH_TRUE;
3342 
3344  /* barge in on prompt */
3345  return SWITCH_STATUS_BREAK;
3346  }
3347  } else {
3348  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Unhandled Speech-Type %s\n", speech_type);
3349  }
3350  }
3351 
3353  switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
3355  state->is_speech = SWITCH_FALSE;
3356 
3357  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "\nis_speech = false; SWITCH_INPUT_TYPE_DTMF; last_digit_time=%" SWITCH_INT64_T_FMT "\n", state->last_digit_time);
3358 
3359  if (!zstr(state->terminators) && strchr(state->terminators, dtmf->digit)) {
3360  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) ACCEPT TERMINATOR %c\n",
3361  switch_channel_get_name(channel), dtmf->digit);
3362 
3363  state->terminator = dtmf->digit;
3364 
3365  /* stop waiting for digits */
3367 
3368  if (switch_test_flag(state, SWITCH_COLLECT_INPUT_DIGITS) && !zstr(state->digits)) {
3369  /* stop waiting for speech */
3371  }
3372 
3373  /* barge-in and break playback on terminator */
3374  return SWITCH_STATUS_BREAK;
3375  }
3376 
3378  int digits_collected = strlen(state->digits);
3379 
3380  if (digits_collected < state->max_digits) {
3381  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) ACCEPT DIGIT %c\n",
3382  switch_channel_get_name(channel), dtmf->digit);
3383  state->digits[digits_collected] = dtmf->digit;
3384  }
3385 
3386  if (digits_collected + 1 >= state->max_digits) {
3387  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) MAX DIGITS COLLECTED\n", switch_channel_get_name(channel));
3388  switch_set_flag(state, SWITCH_COLLECT_INPUT_DIGITS_DONE); // stop waiting for digits
3389  switch_set_flag(state, SWITCH_COLLECT_INPUT_SPEECH_DONE); // stop waiting for speech, too
3390  }
3391  }
3392  return SWITCH_STATUS_BREAK; // got a digit- break for inter-digit timeout / checking results / barge-in
3393  }
3394 
3395  return SWITCH_STATUS_SUCCESS;
3396 }
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:311
#define SWITCH_CHANNEL_SESSION_LOG(x)
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:700
Representation of an event.
Definition: switch_event.h:80
#define zstr(x)
Definition: switch_utils.h:314
_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.
char * switch_event_get_body(switch_event_t *event)
Retrieve the body value from an event.
Definition: switch_event.c:867
const char * cJSON_GetObjectCstr(const cJSON *object, const char *string)
Definition: switch_json.c:22
switch_input_args_t * original_args
#define SWITCH_INT64_T_FMT
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
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.
static void deliver_asr_event(switch_core_session_t *session, switch_event_t *event, switch_input_args_t *args)
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.

◆ switch_ivr_record_file()

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 1052 of file switch_ivr_play_say.c.

References switch_ivr_record_file_event().

1054 {
1055  return switch_ivr_record_file_event(session, fh, file, args, limit, NULL);
1056 }
switch_status_t switch_ivr_record_file_event(switch_core_session_t *session, switch_file_handle_t *fh, const char *file, switch_input_args_t *args, uint32_t limit, switch_event_t *vars)

◆ switch_ivr_record_file_event()

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

Definition at line 404 of file switch_ivr_play_say.c.

References switch_codec_implementation::actual_samples_per_second, arg_recursion_check_start, arg_recursion_check_stop, switch_input_args_t::buf, switch_frame::buflen, switch_input_args_t::buflen, CF_BREAK, CF_VIDEO, CF_VIDEO_BLANK, CF_VIDEO_DECODED_READ, CF_VIDEO_ECHO, switch_file_handle::channels, switch_frame::codec, count, switch_frame::data, switch_stream_handle::data, switch_frame::datalen, switch_codec_implementation::decoded_bytes_per_packet, switch_dtmf_t::digit, switch_input_args_t::dmachine, switch_codec_implementation::encoded_bytes_per_packet, switch_vid_params_s::fps, switch_mm_s::fps, get_recording_var(), switch_vid_params_s::height, switch_codec_implementation::iananame, if(), switch_codec::implementation, switch_input_args_t::input_callback, memset(), merge_recording_variables(), switch_codec_implementation::microseconds_per_packet, switch_file_handle::mm, switch_file_handle::native_rate, switch_codec_implementation::number_of_channels, switch_file_handle::params, switch_file_handle::pre_buffer_datalen, switch_file_handle::prefix, switch_input_args_t::read_frame_callback, recording_var_true(), switch_file_handle::samplerate, switch_frame::samples, switch_file_handle::samples, switch_file_handle::samples_out, switch_codec_implementation::samples_per_packet, SCFC_FLUSH_AUDIO, SFF_CNG, switch_file_handle::silence_hits, 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_FILE_SIZE, SWITCH_AUDIO_COL_STR_FILE_TRIMMED, SWITCH_AUDIO_COL_STR_FILE_TRIMMED_MS, SWITCH_AUDIO_COL_STR_SOFTWARE, SWITCH_AUDIO_COL_STR_TITLE, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, switch_channel_api_on(), switch_channel_clear_flag(), switch_channel_clear_flag_recursive(), switch_channel_dequeue_dtmf(), switch_channel_event_set_data(), switch_channel_execute_on(), switch_channel_execute_on_value(), 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_get_string(), switch_core_file_has_video(), switch_core_file_open, switch_core_file_pre_close(), 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_file_handle::thresh, switch_input_args_t::user_data, switch_mm_s::vh, switch_mm_s::vw, switch_vid_params_s::width, and write_buf().

Referenced by switch_ivr_record_file().

406 {
408  switch_dtmf_t dtmf = { 0 };
409  switch_file_handle_t lfh = { 0 };
410  switch_file_handle_t vfh = { 0 };
411  switch_file_handle_t ind_fh = { 0 };
412  switch_frame_t *read_frame;
413  switch_codec_t codec, write_codec = { 0 };
414  char *codec_name;
416  const char *p;
417  const char *vval;
418  time_t start = 0;
419  uint32_t org_silence_hits = 0;
420  int asis = 0;
421  int32_t sample_start = 0;
422  int waste_resources = 1400, fill_cng = 0;
423  switch_codec_implementation_t read_impl = { 0 };
424  switch_frame_t write_frame = { 0 };
425  unsigned char write_buf[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 };
426  switch_event_t *event;
427  int divisor = 0;
429  int restart_limit_on_dtmf = 0;
430  const char *prefix, *var, *video_file = NULL;
432  int echo_on = 0;
433  const char *file_trimmed_ms = NULL;
434  const char *file_size = NULL;
435  const char *file_trimmed = NULL;
436 
438  return SWITCH_STATUS_FALSE;
439  }
440 
441  if (!file) {
442  return SWITCH_STATUS_FALSE;
443  }
444 
445  prefix = get_recording_var(channel, vars, fh, "sound_prefix");
446 
447  if (!prefix) {
449  }
450 
451  if (!switch_channel_media_ready(channel)) {
452  return SWITCH_STATUS_FALSE;
453  }
454 
455  switch_core_session_get_read_impl(session, &read_impl);
456 
457  if (!(divisor = read_impl.actual_samples_per_second / 8000)) {
458  divisor = 1;
459  }
460 
462 
463  if (!fh) {
464  fh = &lfh;
465  }
466 
467  fh->channels = read_impl.number_of_channels;
468  fh->native_rate = read_impl.actual_samples_per_second;
469 
470  if (fh->samples > 0) {
471  sample_start = fh->samples;
472  fh->samples = 0;
473  }
474 
475 
476  if ((p = get_recording_var(channel, vars, fh, "record_sample_rate"))) {
477  int tmp = 0;
478 
479  tmp = atoi(p);
480 
481  if (switch_is_valid_rate(tmp)) {
482  fh->samplerate = tmp;
483  }
484  }
485 
486  if (!strstr(file, SWITCH_URL_SEPARATOR)) {
487  char *ext;
488 
489  if (!switch_is_file_path(file)) {
490  char *tfile = NULL;
491  char *e;
492 
493  if (*file == '{') {
494  tfile = switch_core_session_strdup(session, file);
495 
496  while (*file == '{') {
497  if ((e = switch_find_end_paren(tfile, '{', '}'))) {
498  *e = '\0';
499  file = e + 1;
500  while(*file == ' ') file++;
501  } else {
502  tfile = NULL;
503  break;
504  }
505  }
506  }
507 
508  file = switch_core_session_sprintf(session, "%s%s%s%s%s", switch_str_nil(tfile), tfile ? "}" : "", prefix, SWITCH_PATH_SEPARATOR, file);
509  }
510  if ((ext = strrchr(file, '.'))) {
511  ext++;
512  } else {
513  ext = read_impl.iananame;
514  file = switch_core_session_sprintf(session, "%s.%s", file, ext);
515  asis = 1;
516  }
517  }
518 
519  if (asis && read_impl.encoded_bytes_per_packet == 0) {
520  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));
523  return SWITCH_STATUS_GENERR;
524  }
525 
526 
527  vval = get_recording_var(channel, vars, fh, "enable_file_write_buffering");
528  if (!vval || switch_true(vval)) {
530  }
531 
532  if (switch_test_flag(fh, SWITCH_FILE_WRITE_APPEND) || recording_var_true(channel, vars, fh, "RECORD_APPEND")) {
533  file_flags |= SWITCH_FILE_WRITE_APPEND;
534  }
535 
536  if (switch_test_flag(fh, SWITCH_FILE_WRITE_OVER) || recording_var_true(channel, vars, fh, "RECORD_WRITE_OVER")) {
537  file_flags |= SWITCH_FILE_WRITE_OVER;
538  }
539 
540  if (!fh->prefix) {
541  fh->prefix = prefix;
542  }
543 
544  if (switch_channel_test_flag(channel, CF_VIDEO)) {
545  switch_vid_params_t vid_params = { 0 };
546 
547  file_flags |= SWITCH_FILE_FLAG_VIDEO;
551  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unable to establish inbound video stream\n");
554  file_flags &= ~SWITCH_FILE_FLAG_VIDEO;
555  } else {
556  switch_core_media_get_vid_params(session, &vid_params);
557  fh->mm.vw = vid_params.width;
558  fh->mm.vh = vid_params.height;
559  fh->mm.fps = vid_params.fps;
560  }
561  }
562 
563  if (switch_core_file_open(fh, file, fh->channels, read_impl.actual_samples_per_second, file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
567  return SWITCH_STATUS_GENERR;
568  }
569 
570 
571  if ((p = get_recording_var(channel, vars, fh, "record_fill_cng"))) {
572  if (!strcasecmp(p, "true")) {
573  fill_cng = 1400;
574  } else {
575  if ((fill_cng = atoi(p)) < 0) {
576  fill_cng = 0;
577  }
578  }
579  }
580 
581  if ((p = switch_channel_get_variable(channel, "record_indication")) || (fh->params && (p = switch_event_get_header(fh->params, "record_indication")))) {
583  waste_resources = 1400;
584 
585  if (switch_core_file_open(&ind_fh,
586  p,
587  read_impl.number_of_channels,
588  read_impl.actual_samples_per_second, flags, NULL) != SWITCH_STATUS_SUCCESS) {
589  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Indication file invalid\n");
590  }
591  }
592 
593  if ((p = get_recording_var(channel, vars, fh, "record_waste_resources"))) {
594 
595  if (!strcasecmp(p, "true")) {
596  waste_resources = 1400;
597  } else {
598  if ((waste_resources = atoi(p)) < 0) {
599  waste_resources = 0;
600  }
601  }
602  }
603 
604  if (fill_cng || waste_resources) {
605  if (switch_core_codec_init(&write_codec,
606  "L16",
607  NULL,
608  NULL,
609  read_impl.actual_samples_per_second,
610  read_impl.microseconds_per_packet / 1000,
611  read_impl.number_of_channels,
614  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activated, ready to waste resources!\n");
615  write_frame.data = write_buf;
616  write_frame.buflen = sizeof(write_buf);
617  write_frame.datalen = read_impl.decoded_bytes_per_packet;
618  write_frame.samples = write_frame.datalen / 2;
619  write_frame.codec = &write_codec;
620  } else {
622  return SWITCH_STATUS_FALSE;
623  }
624  }
625 
626 
627 
630 
631  if ((p = get_recording_var(channel, vars, fh, "record_play_video"))) {
632 
633  video_file = switch_core_session_strdup(session, p);
634 
635  if (switch_core_file_open(&vfh, video_file, fh->channels,
636  read_impl.actual_samples_per_second, vid_play_file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
637  memset(&vfh, 0, sizeof(vfh));
638  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failure opening video playback file.\n");
639  }
640 
644  } else {
646  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Video playback file does not contain video\n");
647  memset(&vfh, 0, sizeof(vfh));
648  }
649  }
650 
651  if (!switch_test_flag(&vfh, SWITCH_FILE_OPEN)) {
652  echo_on = 1;
655  }
656 
658  } else if (switch_channel_test_flag(channel, CF_VIDEO)) {
660  }
661 
662  if (sample_start > 0) {
663  uint32_t pos = 0;
664  switch_core_file_seek(fh, &pos, sample_start, SEEK_SET);
666  fh->samples = 0;
667  }
668 
669 
671  asis = 1;
672  }
673 
674  restart_limit_on_dtmf = recording_var_true(channel, vars, fh, "record_restart_limit_on_dtmf");
675 
676  if ((p = get_recording_var(channel, vars, fh, "record_title"))) {
677  vval = switch_core_session_strdup(session, p);
679  switch_channel_set_variable(channel, "record_title", NULL);
680  }
681 
682  if ((p = get_recording_var(channel, vars, fh, "record_copyright"))) {
683  vval = switch_core_session_strdup(session, p);
685  switch_channel_set_variable(channel, "record_copyright", NULL);
686  }
687 
688  if ((p = get_recording_var(channel, vars, fh, "record_software"))) {
689  vval = switch_core_session_strdup(session, p);
691  switch_channel_set_variable(channel, "record_software", NULL);
692  }
693 
694  if ((p = get_recording_var(channel, vars, fh, "record_artist"))) {
695  vval = switch_core_session_strdup(session, p);
697  switch_channel_set_variable(channel, "record_artist", NULL);
698  }
699 
700  if ((p = get_recording_var(channel, vars, fh, "record_comment"))) {
701  vval = switch_core_session_strdup(session, p);
703  switch_channel_set_variable(channel, "record_comment", NULL);
704  }
705 
706  if ((p = get_recording_var(channel, vars, fh, "record_date"))) {
707  vval = switch_core_session_strdup(session, p);
709  switch_channel_set_variable(channel, "record_date", NULL);
710  }
711 
712 
713  switch_channel_set_variable(channel, "silence_hits_exhausted", "false");
714 
715  if (!asis) {
716  codec_name = "L16";
717  if (switch_core_codec_init(&codec,
718  codec_name,
719  NULL,
720  NULL,
721  read_impl.actual_samples_per_second,
722  read_impl.microseconds_per_packet / 1000,
723  read_impl.number_of_channels,
726  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activated\n");
727  switch_core_session_set_read_codec(session, &codec);
728  } else {
730  "Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate,
731  fh->channels, read_impl.microseconds_per_packet / 1000);
733  if (echo_on) {
736  }
739  }
742 
745  return SWITCH_STATUS_GENERR;
746  }
747  }
748 
749  if (limit) {
750  start = switch_epoch_time_now(NULL);
751  }
752 
753  if (fh->thresh) {
754  if (asis) {
755  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Can't detect silence on a native recording.\n");
756  } else {
757  if (fh->silence_hits) {
758  fh->silence_hits = fh->samplerate * fh->silence_hits / read_impl.samples_per_packet;
759  } else {
760  fh->silence_hits = fh->samplerate * 3 / read_impl.samples_per_packet;
761  }
762  org_silence_hits = fh->silence_hits;
763  }
764  }
765 
766 
768  switch_channel_event_set_data(channel, event);
769  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-File-Path", file);
770  merge_recording_variables(vars, event);
771  switch_event_fire(&event);
772  }
773 
774  {
775  const char *app_exec = NULL;
776  if (vars && (app_exec = switch_event_get_header(vars, "execute_on_record_start"))) {
777  switch_channel_execute_on_value(channel, app_exec);
778  }
779  switch_channel_execute_on(channel, "execute_on_record_start");
780  switch_channel_api_on(channel, "api_on_record_start");
781  }
782 
783  for (;;) {
784  switch_size_t len;
785 
786  if (!switch_channel_ready(channel)) {
787  status = SWITCH_STATUS_FALSE;
788  break;
789  }
790 
791  if (switch_channel_test_flag(channel, CF_BREAK)) {
793  status = SWITCH_STATUS_BREAK;
794  break;
795  }
796 
798 
799  if (start && (switch_epoch_time_now(NULL) - start) > limit) {
800  break;
801  }
802 
803  if (args) {
804  /*
805  dtmf handler function you can hook up to be executed when a digit is dialed during playback
806  if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
807  */
808  if (switch_channel_has_dtmf(channel)) {
809 
810  if (limit && restart_limit_on_dtmf) {
811  start = switch_epoch_time_now(NULL);
812  }
813 
814  if (!args->input_callback && !args->buf && !args->dmachine) {
815  status = SWITCH_STATUS_BREAK;
816  break;
817  }
818  switch_channel_dequeue_dtmf(channel, &dtmf);
819 
820  if (args->dmachine) {
821  char ds[2] = {dtmf.digit, '\0'};
822  if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
823  break;
824  }
825  }
826 
827  if (args->input_callback) {
828  status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
829  } else if (args->buf) {
830  *((char *) args->buf) = dtmf.digit;
831  status = SWITCH_STATUS_BREAK;
832  }
833  }
834 
835  if (args->input_callback) {
836  switch_event_t *event = NULL;
837  switch_status_t ostatus;
838 
840  if ((ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen)) != SWITCH_STATUS_SUCCESS) {
841  status = ostatus;
842  }
843 
844  switch_event_destroy(&event);
845  }
846  }
847 
848  if (status != SWITCH_STATUS_SUCCESS) {
849  break;
850  }
851  }
852 
853  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
854  if (!SWITCH_READ_ACCEPTABLE(status)) {
855  break;
856  }
857 
858  if (args && args->dmachine) {
859  if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
860  break;
861  }
862  }
863 
864  if (args && (args->read_frame_callback)) {
865  if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
866  break;
867  }
868  }
869 
870  if (switch_test_flag(&vfh, SWITCH_FILE_OPEN)) {
872 
874 
875  //switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
876 
878 
880  memset(&vfh, 0, sizeof(vfh));
881 
882  if (switch_core_file_open(&vfh, video_file, fh->channels,
883  read_impl.actual_samples_per_second, vid_play_file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
884  memset(&vfh, 0, sizeof(vfh));
885  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failure opening video playback file.\n");
886  }
887 
889  //switch_core_media_set_video_file(session, &vfh, SWITCH_RW_WRITE);
891  } else {
894  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Video playback file does not contain video\n");
895  memset(&vfh, 0, sizeof(vfh));
896  }
897 
899  }
900 
901  }
902 
903  if (!asis && fh->thresh) {
904  int16_t *fdata = (int16_t *) read_frame->data;
905  uint32_t samples = read_frame->datalen / sizeof(*fdata);
906  uint32_t score, count = 0, j = 0;
907  double energy = 0;
908 
909 
910  for (count = 0; count < samples * read_impl.number_of_channels; count++) {
911  energy += abs(fdata[j++]);
912  }
913 
914  score = (uint32_t) (energy / (samples / divisor));
915 
916  if (score < fh->thresh) {
917  if (!--fh->silence_hits) {
918  switch_channel_set_variable(channel, "silence_hits_exhausted", "true");
919  break;
920  }
921  } else {
922  fh->silence_hits = org_silence_hits;
923  }
924  }
925 
926  write_frame.datalen = read_impl.decoded_bytes_per_packet;
927  write_frame.samples = write_frame.datalen / 2;
928 
929  if (switch_test_flag(&ind_fh, SWITCH_FILE_OPEN)) {
931 
932  if (switch_core_file_read(&ind_fh, write_frame.data, &olen) == SWITCH_STATUS_SUCCESS) {
933  write_frame.samples = olen;
934  write_frame.datalen = olen * 2 * ind_fh.channels;;
935  } else {
936  switch_core_file_close(&ind_fh);
937  }
938 
939  } else if (fill_cng) {
940  switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, read_impl.number_of_channels, fill_cng);
941  } else if (waste_resources) {
942  switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, read_impl.number_of_channels, waste_resources);
943  }
944 
945  if (!switch_test_flag(fh, SWITCH_FILE_PAUSE) && !switch_test_flag(read_frame, SFF_CNG)) {
946  int16_t *data = read_frame->data;
947  len = (switch_size_t) asis ? read_frame->datalen : read_frame->datalen / 2 / fh->channels;
948 
949  if (switch_core_file_write(fh, data, &len) != SWITCH_STATUS_SUCCESS) {
950  break;
951  }
952  } else if (switch_test_flag(read_frame, SFF_CNG) && fill_cng) {
953  len = write_frame.datalen / 2 / fh->channels;
954  if (switch_core_file_write(fh, write_frame.data, &len) != SWITCH_STATUS_SUCCESS) {
955  break;
956  }
957  }
958 
959 
960  if (waste_resources || switch_test_flag(&ind_fh, SWITCH_FILE_OPEN)) {
962  break;
963  }
964  }
965  }
966 
967  if (fill_cng || waste_resources) {
968  switch_core_codec_destroy(&write_codec);
969  }
970 
972  if (echo_on) {
975  }
978  }
980 
985  if (file_trimmed_ms) {
986  switch_channel_set_variable(channel, "record_record_trimmed_ms", file_trimmed_ms);
987  switch_channel_set_variable(channel, "record_trimmed_ms", file_trimmed_ms);
988  }
989  if (file_size) {
990  switch_channel_set_variable(channel, "record_record_file_size", file_size);
991  switch_channel_set_variable(channel, "record_file_size", file_size);
992  }
993  if (file_trimmed) {
994  switch_channel_set_variable(channel, "record_record_trimmed", file_trimmed);
995  switch_channel_set_variable(channel, "record_trimmed", file_trimmed);
996  }
998 
999 
1000  if ((var = switch_channel_get_variable(channel, "record_post_process_exec_api"))) {
1001  char *cmd = switch_core_session_strdup(session, var);
1002  char *data, *expanded = NULL;
1003  switch_stream_handle_t stream = { 0 };
1004 
1005  SWITCH_STANDARD_STREAM(stream);
1006 
1007  if ((data = strchr(cmd, ':'))) {
1008  *data++ = '\0';
1009  expanded = switch_channel_expand_variables(channel, data);
1010  }
1011 
1012  switch_api_execute(cmd, expanded, session, &stream);
1013 
1014  if (expanded && expanded != data) {
1015  free(expanded);
1016  }
1017 
1018  switch_safe_free(stream.data);
1019 
1020  }
1021 
1022  if (read_impl.actual_samples_per_second && fh->native_rate >= 1000) {
1023  switch_channel_set_variable_printf(channel, "record_seconds", "%d", fh->samples_out / fh->native_rate);
1024  switch_channel_set_variable_printf(channel, "record_ms", "%d", fh->samples_out / (fh->native_rate / 1000));
1025 
1026  }
1027 
1028  switch_channel_set_variable_printf(channel, "record_samples", "%d", fh->samples_out);
1029 
1031  switch_channel_event_set_data(channel, event);
1032  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-File-Path", file);
1033  merge_recording_variables(vars, event);
1034  switch_event_fire(&event);
1035  }
1036 
1037  {
1038  const char *app_exec = NULL;
1039  if (vars && (app_exec = switch_event_get_header(vars, "execute_on_record_stop"))) {
1040  switch_channel_execute_on_value(channel, app_exec);
1041  }
1042  switch_channel_execute_on(channel, "execute_on_record_stop");
1043  switch_channel_api_on(channel, "api_on_record_stop");
1044  }
1045 
1047 
1049  return status;
1050 }
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:413
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
#define switch_core_media_gen_key_frame(_session)
switch_status_t switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix)
void switch_channel_set_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
switch_status_t switch_core_file_pre_close(_In_ switch_file_handle_t *fh)
Pre close an open file handle, then can get file size etc., no more wirte to the file.
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 ...
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
#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:796
switch_status_t switch_channel_execute_on_value(switch_channel_t *channel, const char *variable_value)
#define switch_core_file_open(_fh, _file_path, _channels, _rate, _flags, _pool)
Open a media file using file format modules.
Definition: switch_core.h:1963
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:590
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:126
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.
switch_status_t switch_core_file_get_string(_In_ switch_file_handle_t *fh, switch_audio_col_t col, const char **string)
get metadata of the desired string
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:913
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:56
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:124
const switch_codec_implementation_t * implementation
uint32_t buflen
Definition: switch_frame.h:70
static const char * get_recording_var(switch_channel_t *channel, switch_event_t *vars, switch_file_handle_t *fh, const char *name)
if((uint32_t)(unpack->cur - unpack->buf) > unpack->buflen)
uint32_t datalen
Definition: switch_frame.h:68
#define switch_core_session_request_video_refresh(_s)
Definition: switch_core.h:2881
#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:885
switch_input_callback_function_t input_callback
An abstraction of a data frame.
Definition: switch_frame.h:54
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:1693
#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:82
switch_read_frame_callback_function_t read_frame_callback
static void merge_recording_variables(switch_event_t *vars, switch_event_t *event)
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:993
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)
#define switch_clear_flag_locked(obj, flag)
Clear a flag on an arbitrary object.
Definition: switch_utils.h:717
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)
#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:384
static switch_bool_t switch_is_file_path(const char *file)
uint32_t samples
Definition: switch_frame.h:72
#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:322
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
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:378
switch_status_t switch_core_media_lock_video_file(switch_core_session_t *session, switch_rw_t rw)
int count
Definition: switch_cJSON.h:204
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session&#39;s pool.
Definition: switch_core.h:719
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.
switch_status_t switch_channel_api_on(switch_channel_t *channel, const char *variable_prefix)
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
#define SWITCH_READ_ACCEPTABLE(status)
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:236
switch_ivr_dmachine_t * dmachine
static int recording_var_true(switch_channel_t *channel, switch_event_t *vars, switch_file_handle_t *fh, const char *name)

◆ teletone_handler()

static int teletone_handler ( teletone_generation_session_t ts,
teletone_tone_map_t map 
)
static

Definition at line 1058 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().

1059 {
1060  switch_buffer_t *audio_buffer = ts->user_data;
1061  int wrote;
1062 
1063  if (!audio_buffer) {
1064  return -1;
1065  }
1066 
1067  wrote = teletone_mux_tones(ts, map);
1068  switch_buffer_write(audio_buffer, ts->buffer, wrote * 2);
1069 
1070  return 0;
1071 }
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.