static int load_module(void) { int res = 0; int x, y, idx = 0; trans_size = ARRAY_LEN(id_list) * ARRAY_LEN(id_list); if (!(translators = ast_calloc(1, sizeof(struct ast_translator) * trans_size))) { return AST_MODULE_LOAD_FAILURE; } for (x = 0; x < ARRAY_LEN(id_list); x++) { for (y = 0; y < ARRAY_LEN(id_list); y++) { if (x == y) { continue; } translators[idx].newpvt = resamp_new; translators[idx].destroy = resamp_destroy; translators[idx].framein = resamp_framein; translators[idx].desc_size = 0; translators[idx].buffer_samples = (OUTBUF_SIZE / sizeof(int16_t)); translators[idx].buf_size = OUTBUF_SIZE; ast_format_set(&translators[idx].src_format, id_list[x], 0); ast_format_set(&translators[idx].dst_format, id_list[y], 0); snprintf(translators[idx].name, sizeof(translators[idx].name), "slin %dkhz -> %dkhz", ast_format_rate(&translators[idx].src_format), ast_format_rate(&translators[idx].dst_format)); res |= ast_register_translator(&translators[idx]); idx++; } } return AST_MODULE_LOAD_SUCCESS; }
static int resamp_new(struct ast_trans_pvt *pvt) { int err; if (!(pvt->pvt = speex_resampler_init(1, ast_format_rate(&pvt->t->src_format), ast_format_rate(&pvt->t->dst_format), 5, &err))) { return -1; } return 0; }
static int speex_callback(struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction) { struct ast_datastore *datastore = NULL; struct speex_direction_info *sdi = NULL; struct speex_info *si = NULL; char source[80]; /* If the audiohook is stopping it means the channel is shutting down.... but we let the datastore destroy take care of it */ if (audiohook->status == AST_AUDIOHOOK_STATUS_DONE || frame->frametype != AST_FRAME_VOICE) { return -1; } /* We are called with chan already locked */ if (!(datastore = ast_channel_datastore_find(chan, &speex_datastore, NULL))) { return -1; } si = datastore->data; sdi = (direction == AST_AUDIOHOOK_DIRECTION_READ) ? si->rx : si->tx; if (!sdi) { return -1; } if ((sdi->samples != frame->samples) || (ast_format_rate(&frame->subclass.format) != si->lastrate)) { si->lastrate = ast_format_rate(&frame->subclass.format); if (sdi->state) { speex_preprocess_state_destroy(sdi->state); } if (!(sdi->state = speex_preprocess_state_init((sdi->samples = frame->samples), si->lastrate))) { return -1; } speex_preprocess_ctl(sdi->state, SPEEX_PREPROCESS_SET_AGC, &sdi->agc); if (sdi->agc) { speex_preprocess_ctl(sdi->state, SPEEX_PREPROCESS_SET_AGC_LEVEL, &sdi->agclevel); } speex_preprocess_ctl(sdi->state, SPEEX_PREPROCESS_SET_DENOISE, &sdi->denoise); } speex_preprocess(sdi->state, frame->data.ptr, NULL); snprintf(source, sizeof(source), "%s/speex", frame->src); if (frame->mallocd & AST_MALLOCD_SRC) { ast_free((char *) frame->src); } frame->src = ast_strdup(source); frame->mallocd |= AST_MALLOCD_SRC; return 0; }
static int find_best_byid_cb(void *obj, void *arg, int flag) { struct ast_format *format = obj; struct byid_data *data = arg; if (data->id != format->id) { return 0; } if (!data->result->id || (ast_format_rate(data->result) < ast_format_rate(format))) { ast_format_copy(data->result, format); } return 0; }
static void mixmonitor_save_prep(struct mixmonitor *mixmonitor, char *filename, struct ast_filestream **fs, unsigned int *oflags, int *errflag) { /* Initialize the file if not already done so */ char *ext = NULL; char *last_slash = NULL; if (!ast_strlen_zero(filename)) { if (!*fs && !*errflag && !mixmonitor->mixmonitor_ds->fs_quit) { *oflags = O_CREAT | O_WRONLY; *oflags |= ast_test_flag(mixmonitor, MUXFLAG_APPEND) ? O_APPEND : O_TRUNC; last_slash = strrchr(filename, '/'); if ((ext = strrchr(filename, '.')) && (ext > last_slash)) { *(ext++) = '\0'; } else { ext = "raw"; } if (!(*fs = ast_writefile(filename, ext, NULL, *oflags, 0, 0666))) { ast_log(LOG_ERROR, "Cannot open %s.%s\n", filename, ext); *errflag = 1; } else { struct ast_filestream *tmp = *fs; mixmonitor->mixmonitor_ds->samp_rate = MAX(mixmonitor->mixmonitor_ds->samp_rate, ast_format_rate(&tmp->fmt->format)); } } } }