*/
SWITCH_DECLARE(switch_status) switch_core_session_set_read_codec(switch_core_session *session, switch_codec *codec);
+/*!
+ \brief Retrieve the read codec from a given session
+ \param session session to retrieve from
+ \return a pointer to the codec
+*/
+SWITCH_DECLARE(switch_codec *) switch_core_session_get_read_codec(switch_core_session *session);
+
/*!
\brief Assign the write codec to a given session
\param session session to add the codec to
\return SWITCH_STATUS_SUCCESS if successful
*/
SWITCH_DECLARE(switch_status) switch_core_session_set_write_codec(switch_core_session *session, switch_codec *codec);
-///\}
+/*!
+ \brief Retrieve the write codec from a given session
+ \param session session to retrieve from
+ \return a pointer to the codec
+*/
+SWITCH_DECLARE(switch_codec *) switch_core_session_get_write_codec(switch_core_session *session);
+
+///\}
///\defgroup db Database Functions
///\ingroup core1
///\{
/*!
\brief Read media from a file handle
- \param fh the file handle to read from
+ \param fh the file handle to read from (must be initilized by you memset all 0 for read, fill in channels and rate for write)
\param data the buffer to read the data to
\param len the max size of the buffer
\return SWITCH_STATUS_SUCCESS with len adjusted to the bytes read if successful
char *file,
char *timer_name,
switch_dtmf_callback_function dtmf_callback);
+
+
+
+/*!
+ \brief record a file from the session to a file
+ \param session the session to record from
+ \param file the path to the file
+ \param dtmf_callback code to execute if any dtmf is dialed during the recording
+ \return SWITCH_STATUS_SUCCESS if all is well
+*/
+SWITCH_DECLARE(switch_status) switch_ivr_record_file(switch_core_session *session,
+ char *file,
+ switch_dtmf_callback_function dtmf_callback);
/** @} */
}
+
+void record_function(switch_core_session *session, char *data)
+{
+ switch_channel *channel;
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
+
+ if (switch_ivr_record_file(session, data, on_dtmf) != SWITCH_STATUS_SUCCESS) {
+ switch_channel_hangup(channel);
+ }
+
+}
+
+static const switch_application_interface record_application_interface = {
+ /*.interface_name */ "record",
+ /*.application_function */ record_function
+};
+
static const switch_application_interface playback_application_interface = {
/*.interface_name */ "playback",
- /*.application_function */ playback_function
+ /*.application_function */ playback_function,
+ NULL,NULL,NULL,
+ /*.next*/ &record_application_interface
};
static const switch_loadable_module_interface mod_playback_module_interface = {
sndfile_context *context;
int mode = 0;
char *ext;
-
+ int ready = 1;
+
if (!(ext = strrchr(path, '.'))) {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Invalid Format\n");
return SWITCH_STATUS_GENERR;
return SWITCH_STATUS_GENERR;
}
-
if (!(context = switch_core_alloc(handle->memory_pool, sizeof(*context)))) {
return SWITCH_STATUS_MEMERR;
}
- if (!strcmp(ext, "r8") || !strcmp(ext, "raw")) {
- context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 8000;
- }
+ if (mode & SFM_WRITE) {
+ context->sfinfo.channels = handle->channels;
+ context->sfinfo.samplerate = handle->samplerate;
+ if (handle->samplerate == 8000 || handle->samplerate == 16000) {
+ context->sfinfo.format |= SF_FORMAT_PCM_16;
+ } else if (handle->samplerate == 24000) {
+ context->sfinfo.format |= SF_FORMAT_PCM_24;
+ } else if (handle->samplerate == 32000) {
+ context->sfinfo.format |= SF_FORMAT_PCM_32;
+ }
- if (!strcmp(ext, "r16")) {
- context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 16000;
+ /* Could add more else if() but i am too lazy atm.. */
+ if (!strcasecmp(ext, "wav")) {
+ context->sfinfo.format |= SF_FORMAT_WAV;
+ } else {
+ ready = 0;
+ }
}
- if (!strcmp(ext, "r24")) {
- context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_24;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 24000;
- }
- if (!strcmp(ext, "r32")) {
- context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_32;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 32000;
+ if (!ready) {
+ if (!strcmp(ext, "r8") || !strcmp(ext, "raw")) {
+ context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
+ context->sfinfo.channels = 1;
+ context->sfinfo.samplerate = 8000;
+ } else if (!strcmp(ext, "r16")) {
+ context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
+ context->sfinfo.channels = 1;
+ context->sfinfo.samplerate = 16000;
+ } else if (!strcmp(ext, "r24")) {
+ context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_24;
+ context->sfinfo.channels = 1;
+ context->sfinfo.samplerate = 24000;
+ } else if (!strcmp(ext, "r32")) {
+ context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_32;
+ context->sfinfo.channels = 1;
+ context->sfinfo.samplerate = 32000;
+ } else if (!strcmp(ext, "gsm")) {
+ context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_GSM610;
+ context->sfinfo.channels = 1;
+ context->sfinfo.samplerate = 8000;
+ }
}
- if (!strcmp(ext, "gsm")) {
- context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_GSM610;
- context->sfinfo.channels = 1;
- context->sfinfo.samplerate = 8000;
- }
+
+ if ((mode & SFM_WRITE) && sf_format_check (&context->sfinfo) == 0) {
+ switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Error : file format is invalid (0x%08X).\n", context->sfinfo.format);
+ return SWITCH_STATUS_GENERR;
+ };
+
if (!(context->handle = sf_open(path, mode, &context->sfinfo))) {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Error Opening File [%s] [%s]\n", path,
return SWITCH_STATUS_SUCCESS;
}
+SWITCH_DECLARE(switch_codec *) switch_core_session_get_read_codec(switch_core_session *session)
+{
+ return session->read_codec;
+}
SWITCH_DECLARE(switch_status) switch_core_session_set_write_codec(switch_core_session *session, switch_codec *codec)
{
return SWITCH_STATUS_SUCCESS;
}
+SWITCH_DECLARE(switch_codec *) switch_core_session_get_write_codec(switch_core_session *session)
+{
+ return session->write_codec;
+}
+
SWITCH_DECLARE(switch_status) switch_core_codec_init(switch_codec *codec, char *codec_name, int rate, int ms,
int channels, switch_codec_flag flags,
const switch_codec_settings *codec_settings,
char *ext;
switch_status status;
- memset(fh, 0, sizeof(*fh));
-
if (!(ext = strrchr(file_path, '.'))) {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Invalid Format\n");
return SWITCH_STATUS_FALSE;
#include <switch_ivr.h>
-/* TBD (Lots! there is only 1 function in here lol) */
+/* TBD (Lots! there are only 2 functions in here lol) */
+
+
+SWITCH_DECLARE(switch_status) switch_ivr_record_file(switch_core_session *session,
+ char *file,
+ switch_dtmf_callback_function dtmf_callback)
+{
+ switch_channel *channel;
+ char dtmf[128];
+ switch_file_handle fh;
+ switch_frame *read_frame;
+ switch_codec codec, *read_codec;
+ char *codec_name;
+ switch_status status = SWITCH_STATUS_SUCCESS;
+
+ memset(&fh, 0, sizeof(fh));
+
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
+
+ read_codec = switch_core_session_get_read_codec(session);
+ assert(read_codec != NULL);
+
+ fh.channels = read_codec->implementation->number_of_channels;
+ fh.samplerate = read_codec->implementation->samples_per_second;
+
+
+ if (switch_core_file_open(&fh,
+ file,
+ SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT,
+ switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
+ switch_channel_hangup(channel);
+ return SWITCH_STATUS_GENERR;
+ }
+
+ switch_channel_answer(channel);
+
+
+ codec_name = "L16";
+ if (switch_core_codec_init(&codec,
+ codec_name,
+ read_codec->implementation->samples_per_second,
+ read_codec->implementation->microseconds_per_frame / 1000,
+ read_codec->implementation->number_of_channels,
+ SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
+ NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
+ switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Raw Codec Activated\n");
+ switch_core_session_set_read_codec(session, &codec);
+ } else {
+ switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Raw Codec Activation Failed %s@%dhz %d channels %dms\n",
+ codec_name, fh.samplerate, fh.channels, read_codec->implementation->microseconds_per_frame / 1000);
+ switch_core_file_close(&fh);
+ return SWITCH_STATUS_GENERR;
+ }
+
+
+ while (switch_channel_get_state(channel) == CS_EXECUTE) {
+ int len;
+
+ if (dtmf_callback) {
+ /*
+ dtmf handler function you can hook up to be executed when a digit is dialed during playback
+ if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
+ */
+ if (switch_channel_has_dtmf(channel)) {
+ switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
+ status = dtmf_callback(session, dtmf);
+ }
+
+ if (status != SWITCH_STATUS_SUCCESS) {
+ break;
+ }
+ }
+
+ if (switch_core_session_read_frame(session, &read_frame, -1, 0) != SWITCH_STATUS_SUCCESS) {
+ break;
+ }
+
+ len = read_frame->datalen / 2;
+ switch_core_file_write(&fh, read_frame->data, &len);
+ }
+
+ switch_core_session_set_read_codec(session, read_codec);
+ switch_core_file_close(&fh);
+
+ return status;
+}
SWITCH_DECLARE(switch_status) switch_ivr_play_file(switch_core_session *session,
char *file,
int stream_id;
switch_status status = SWITCH_STATUS_SUCCESS;
+ memset(&fh, 0, sizeof(fh));
channel = switch_core_session_get_channel(session);
assert(channel != NULL);
}
} else { /* time off the channel (if you must) */
switch_frame *read_frame;
- switch_core_session_read_frame(session, &read_frame, -1, 0);
+ if (switch_core_session_read_frame(session, &read_frame, -1, 0) != SWITCH_STATUS_SUCCESS) {
+ break;
+ }
}
}