struct effect * compress_effect_init(struct effect_info *ei, struct stream_info *istream, char *channel_selector, int argc, char **argv) { struct effect *e; struct compress_state *state; if (argc != 5) { LOG(LL_ERROR, "dsp: %s: usage: %s\n", argv[0], ei->usage); return NULL; } state = calloc(1, sizeof(struct compress_state)); state->thresh_db = atof(argv[1]); state->thresh = pow(10, state->thresh_db / 20); state->ratio = atof(argv[2]); CHECK_RANGE(state->ratio > 0, "ratio", goto fail); state->ratio = 1 - 1 / state->ratio; state->attack = atof(argv[3]); CHECK_RANGE(state->attack >= 0, "attack", goto fail); state->attack = (state->attack == 0) ? 0 : pow(10, -10 / state->attack / istream->fs / 20); state->release = atof(argv[4]); CHECK_RANGE(state->release >= 0, "release", goto fail); state->release = (state->release == 0) ? HUGE_VAL : pow(10, 10 / state->release / istream->fs / 20); state->gain = 1.0; e = calloc(1, sizeof(struct effect)); e->name = ei->name; e->istream.fs = e->ostream.fs = istream->fs; e->istream.channels = e->ostream.channels = istream->channels; e->channel_selector = NEW_SELECTOR(istream->channels); COPY_SELECTOR(e->channel_selector, channel_selector, istream->channels); e->worst_case_ratio = e->ratio = 1.0; e->run = compress_effect_run; e->reset = compress_effect_reset; e->drain = compress_effect_drain; e->destroy = compress_effect_destroy; e->data = state; return e; fail: free(state); return NULL; }
struct effect * remix_effect_init(struct effect_info *ei, struct stream_info *istream, char *channel_selector, int argc, char **argv) { struct effect *e; struct remix_state *state; int i, out_channels; if (argc <= 1) { LOG(LL_ERROR, "dsp: %s: usage: %s\n", argv[0], ei->usage); return NULL; } out_channels = argc - 1; state = calloc(1, sizeof(struct remix_state)); state->channel_selectors = calloc(out_channels, sizeof(char *)); for (i = 0; i < out_channels; ++i) { state->channel_selectors[i] = NEW_SELECTOR(istream->channels); if (strcmp(argv[i + 1], ".") != 0 && parse_selector(argv[i + 1], state->channel_selectors[i], istream->channels)) goto fail; } e = calloc(1, sizeof(struct effect)); e->name = ei->name; e->istream.fs = e->ostream.fs = istream->fs; e->istream.channels = istream->channels; e->ostream.channels = out_channels; e->worst_case_ratio = e->ratio = (double) e->ostream.channels / e->istream.channels; e->run = remix_effect_run; e->reset = remix_effect_reset; e->drain = remix_effect_drain; e->destroy = remix_effect_destroy; e->data = state; return e; fail: if (state->channel_selectors) for (i = 0; i < out_channels; ++i) free(state->channel_selectors[i]); free(state->channel_selectors); free(state); return NULL; }
struct codec * sgen_codec_init(const char *path, const char *type, const char *enc, int fs, int channels, int endian, int mode) { char *args = NULL, *arg, *gen_type, *len_str, *next_arg, *next_type, *value, *endptr; int parse_ret; struct codec *c; struct sgen_state *state; struct sgen_generator *g; c = calloc(1, sizeof(struct codec)); c->path = path; c->type = type; c->enc = "sample_t"; c->fs = fs; c->channels = channels; c->prec = 53; c->frames = -1; c->read = sgen_read; c->write = sgen_write; c->seek = sgen_seek; c->delay = sgen_delay; c->drop = sgen_drop; c->pause = sgen_pause; c->destroy = sgen_destroy; state = calloc(1, sizeof(struct sgen_state)); state->n = 0; c->data = state; args = arg = strdup(path); len_str = isolate(arg, '+'); if (*len_str != '\0') { c->frames = parse_len(len_str, fs, &endptr); if (check_endptr(type, len_str, endptr, "length")) goto fail; if (c->frames <= 0) { LOG(LL_ERROR, "%s: %s: error: length cannot be <= 0\n", dsp_globals.prog_name, type); goto fail; } /* LOG(LL_VERBOSE, "%s: %s: info: length=%zd\n", dsp_globals.prog_name, type, c->frames); */ } while (*arg != '\0') { next_type = isolate(arg, '/'); next_arg = isolate(arg, ':'); value = isolate(arg, '@'); /* LOG(LL_VERBOSE, "%s: %s: info: type=%s channel_selector=%s\n", dsp_globals.prog_name, type, arg, value); */ state->g = realloc(state->g, (state->n + 1) * sizeof(struct sgen_generator)); g = &state->g[state->n]; memset(g, 0, sizeof(struct sgen_generator)); g->channel_selector = NEW_SELECTOR(channels); SET_SELECTOR(g->channel_selector, channels); ++state->n; gen_type = arg; if (strcmp(gen_type, "delta") == 0) g->type = SGEN_TYPE_DELTA; else if (strcmp(gen_type, "sine") == 0) g->type = SGEN_TYPE_SINE; else { LOG(LL_ERROR, "%s: %s: error: illegal type: %s\n", dsp_globals.prog_name, type, gen_type); goto fail; } sgen_init_generator(g, c); if (*value != '\0' && parse_selector(value, g->channel_selector, channels)) goto fail; arg = next_arg; while (*arg != '\0') { next_arg = isolate(arg, ':'); value = isolate(arg, '='); /* LOG(LL_VERBOSE, "%s: %s: %s: arg: key=%s value=%s\n", dsp_globals.prog_name, type, gen_type, arg, value); */ parse_ret = sgen_parse_param(g, c, type, arg, value); if (parse_ret == 1) { LOG(LL_ERROR, "%s: %s: %s: error: illegal parameter: %s\n", dsp_globals.prog_name, type, gen_type, arg); goto fail; } else if (parse_ret == -1) goto fail; arg = next_arg; } sgen_prepare_generator(g, c); arg = next_type; } done: free(args); return c; fail: sgen_destroy(c); free(c); c = NULL; goto done; }