Newer
Older
Kevin P. Fleming
committed
result = read_frame;
Kevin P. Fleming
committed
ast_frfree(write_frame);
}
Kevin P. Fleming
committed
} else {
if (need_dup) {
result = ast_frdup(read_frame);
result->next = ast_frdup(write_frame);
} else {
result = read_frame;
result->next = write_frame;
}
}
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 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,
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
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
.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;
}
};