Newer
Older
static void silence_generator_release(struct ast_channel *chan, void *data)
{
/* nothing to do */
}
static int silence_generator_generate(struct ast_channel *chan, void *data, int len, int samples)
{
if (samples == 160) {
Kevin P. Fleming
committed
short buf[160] = { 0, };
struct ast_frame frame = {
.frametype = AST_FRAME_VOICE,
.subclass = AST_FORMAT_SLINEAR,
.data = buf,
.samples = 160,
.datalen = sizeof(buf),
};
if (ast_write(chan, &frame))
return -1;
} else {
short buf[samples];
int x;
struct ast_frame frame = {
.frametype = AST_FRAME_VOICE,
.subclass = AST_FORMAT_SLINEAR,
Kevin P. Fleming
committed
.data = buf,
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
.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);
}
/*! \ brief Convert channel reloadreason (ENUM) to text string for manager event */
const char *channelreloadreason2txt(enum channelreloadreason reason) {
switch (reason) {
case CHANNEL_MODULE_LOAD: return "LOAD (Channel module load)";
break;
case CHANNEL_MODULE_RELOAD: return "RELOAD (Channel module reload)";
break;
case CHANNEL_CLI_RELOAD: return "CLIRELOAD (Channel module reload by CLI command)";
break;
default: return "MANAGERRELOAD (Channel module reload by manager)";
break;
}
};