1
0
mirror of https://github.com/signalwire/freeswitch.git synced 2025-04-17 01:02:12 +00:00

make test 'record' app in app_playback.c

You are best off doing wav (trust me) 
It can record at 8 16 22 and 32 khz if you can manage to have a channel at that speed.

syntax [record /tmp/blah.wav] 

dial * to end (dtmf only works in iax and portaudio {beg file to add it to mod_exosip})



git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@453 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2006-01-27 01:46:14 +00:00
parent 954fe31140
commit 48ae14726b
6 changed files with 196 additions and 32 deletions
src
include
mod
applications/mod_playback
formats/mod_sndfile
switch_core.cswitch_ivr.c

@ -641,6 +641,13 @@ SWITCH_DECLARE(switch_status) switch_core_codec_destroy(switch_codec *codec);
*/ */
SWITCH_DECLARE(switch_status) switch_core_session_set_read_codec(switch_core_session *session, switch_codec *codec); 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 \brief Assign the write codec to a given session
\param session session to add the codec to \param session session to add the codec to
@ -648,8 +655,15 @@ SWITCH_DECLARE(switch_status) switch_core_session_set_read_codec(switch_core_ses
\return SWITCH_STATUS_SUCCESS if successful \return SWITCH_STATUS_SUCCESS if successful
*/ */
SWITCH_DECLARE(switch_status) switch_core_session_set_write_codec(switch_core_session *session, switch_codec *codec); 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 ///\defgroup db Database Functions
///\ingroup core1 ///\ingroup core1
///\{ ///\{
@ -684,7 +698,7 @@ SWITCH_DECLARE(switch_status) switch_core_file_open(switch_file_handle *fh, char
/*! /*!
\brief Read media from a file handle \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 data the buffer to read the data to
\param len the max size of the buffer \param len the max size of the buffer
\return SWITCH_STATUS_SUCCESS with len adjusted to the bytes read if successful \return SWITCH_STATUS_SUCCESS with len adjusted to the bytes read if successful

@ -64,6 +64,19 @@ SWITCH_DECLARE(switch_status) switch_ivr_play_file(switch_core_session *session,
char *file, char *file,
char *timer_name, char *timer_name,
switch_dtmf_callback_function dtmf_callback); 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);
/** @} */ /** @} */

@ -73,9 +73,29 @@ void playback_function(switch_core_session *session, char *data)
} }
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 = { static const switch_application_interface playback_application_interface = {
/*.interface_name */ "playback", /*.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 = { static const switch_loadable_module_interface mod_playback_module_interface = {

@ -46,7 +46,8 @@ switch_status sndfile_file_open(switch_file_handle *handle, char *path)
sndfile_context *context; sndfile_context *context;
int mode = 0; int mode = 0;
char *ext; char *ext;
int ready = 1;
if (!(ext = strrchr(path, '.'))) { if (!(ext = strrchr(path, '.'))) {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Invalid Format\n"); switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Invalid Format\n");
return SWITCH_STATUS_GENERR; return SWITCH_STATUS_GENERR;
@ -67,40 +68,60 @@ switch_status sndfile_file_open(switch_file_handle *handle, char *path)
return SWITCH_STATUS_GENERR; return SWITCH_STATUS_GENERR;
} }
if (!(context = switch_core_alloc(handle->memory_pool, sizeof(*context)))) { if (!(context = switch_core_alloc(handle->memory_pool, sizeof(*context)))) {
return SWITCH_STATUS_MEMERR; return SWITCH_STATUS_MEMERR;
} }
if (!strcmp(ext, "r8") || !strcmp(ext, "raw")) { if (mode & SFM_WRITE) {
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16; context->sfinfo.channels = handle->channels;
context->sfinfo.channels = 1; context->sfinfo.samplerate = handle->samplerate;
context->sfinfo.samplerate = 8000; 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;
}
/* 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, "r16")) {
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16; if (!ready) {
context->sfinfo.channels = 1; if (!strcmp(ext, "r8") || !strcmp(ext, "raw")) {
context->sfinfo.samplerate = 16000; 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, "r24")) {
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_24;
context->sfinfo.channels = 1;
context->sfinfo.samplerate = 24000;
}
if (!strcmp(ext, "r32")) { if ((mode & SFM_WRITE) && sf_format_check (&context->sfinfo) == 0) {
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_32; switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Error : file format is invalid (0x%08X).\n", context->sfinfo.format);
context->sfinfo.channels = 1; return SWITCH_STATUS_GENERR;
context->sfinfo.samplerate = 32000; };
}
if (!strcmp(ext, "gsm")) {
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_GSM610;
context->sfinfo.channels = 1;
context->sfinfo.samplerate = 8000;
}
if (!(context->handle = sf_open(path, mode, &context->sfinfo))) { if (!(context->handle = sf_open(path, mode, &context->sfinfo))) {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Error Opening File [%s] [%s]\n", path, switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Error Opening File [%s] [%s]\n", path,

@ -212,6 +212,10 @@ SWITCH_DECLARE(switch_status) switch_core_session_set_read_codec(switch_core_ses
return SWITCH_STATUS_SUCCESS; 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) SWITCH_DECLARE(switch_status) switch_core_session_set_write_codec(switch_core_session *session, switch_codec *codec)
{ {
@ -221,6 +225,11 @@ SWITCH_DECLARE(switch_status) switch_core_session_set_write_codec(switch_core_se
return SWITCH_STATUS_SUCCESS; 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, SWITCH_DECLARE(switch_status) switch_core_codec_init(switch_codec *codec, char *codec_name, int rate, int ms,
int channels, switch_codec_flag flags, int channels, switch_codec_flag flags,
const switch_codec_settings *codec_settings, const switch_codec_settings *codec_settings,
@ -361,8 +370,6 @@ SWITCH_DECLARE(switch_status) switch_core_file_open(switch_file_handle *fh, char
char *ext; char *ext;
switch_status status; switch_status status;
memset(fh, 0, sizeof(*fh));
if (!(ext = strrchr(file_path, '.'))) { if (!(ext = strrchr(file_path, '.'))) {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Invalid Format\n"); switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Invalid Format\n");
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;

@ -33,7 +33,93 @@
#include <switch_ivr.h> #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, SWITCH_DECLARE(switch_status) switch_ivr_play_file(switch_core_session *session,
char *file, char *file,
@ -56,6 +142,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_play_file(switch_core_session *session,
int stream_id; int stream_id;
switch_status status = SWITCH_STATUS_SUCCESS; switch_status status = SWITCH_STATUS_SUCCESS;
memset(&fh, 0, sizeof(fh));
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
assert(channel != NULL); assert(channel != NULL);
@ -165,7 +252,9 @@ SWITCH_DECLARE(switch_status) switch_ivr_play_file(switch_core_session *session,
} }
} else { /* time off the channel (if you must) */ } else { /* time off the channel (if you must) */
switch_frame *read_frame; 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;
}
} }
} }