diff options
author | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2005-11-01 17:22:25 +0000 |
---|---|---|
committer | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2005-11-01 17:22:25 +0000 |
commit | cd7ee5f7cd6d49a4ed351fa7df55c2ca3289de89 (patch) | |
tree | b24f65814e64ea93c42d8db91cbc40459344bbc7 /channel.c | |
parent | dced94c17e806027133032e9c1083a2b98fdf790 (diff) |
optionally send silence during recording (issue #5135)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@6925 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channel.c')
-rwxr-xr-x | channel.c | 97 |
1 files changed, 97 insertions, 0 deletions
@@ -3921,3 +3921,100 @@ struct ast_frame *ast_channel_spy_read_frame(struct ast_channel_spy *spy, unsign return result; } + +static void *silence_generator_alloc(struct ast_channel *chan, void *data) +{ + /* just store the data pointer in the channel structure */ + return data; +} + +static void silence_generator_release(struct ast_channel *chan, void *data) +{ + /* nothing to do */ +} + +static short normal_silence_buf[160] = { 0, }; +static struct ast_frame normal_silence_frame = { + .frametype = AST_FRAME_VOICE, + .subclass = AST_FORMAT_SLINEAR, + .data = normal_silence_buf, + .samples = 160, + .datalen = sizeof(normal_silence_buf), +}; + +static int silence_generator_generate(struct ast_channel *chan, void *data, int len, int samples) +{ + if (samples == 160) { + if (ast_write(chan, &normal_silence_frame)) + return -1; + } else { + short buf[samples]; + int x; + struct ast_frame frame = { + .frametype = AST_FRAME_VOICE, + .subclass = AST_FORMAT_SLINEAR, + .data = normal_silence_buf, + .samples = samples, + .datalen = sizeof(buf), + }; + + for (x = 0; x < samples; x++) + buf[x] = 0; + + if (ast_write(chan, &frame)) + return -1; + } + + return 0; +} + +static struct ast_generator silence_generator = { + .alloc = silence_generator_alloc, + .release = silence_generator_release, + .generate = silence_generator_generate, +}; + +struct ast_silence_generator { + int old_write_format; +}; + +struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_channel *chan) +{ + struct ast_silence_generator *state; + + if (!(state = calloc(1, sizeof(*state)))) { + ast_log(LOG_WARNING, "Could not allocate state structure\n"); + return NULL; + } + + state->old_write_format = chan->writeformat; + + if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { + ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); + free(state); + return NULL; + } + + ast_activate_generator(chan, &silence_generator, state); + + if (option_debug) + ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name); + + return state; +} + +void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state) +{ + if (!state) + return; + + ast_deactivate_generator(chan); + + if (option_debug) + ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name); + + if (ast_set_write_format(chan, state->old_write_format) < 0) + ast_log(LOG_ERROR, "Could not return write format to its original state\n"); + + free(state); +} |