ref: e65365f609d6b86b8a4267eac9eed755683cb000
dir: /src/core/makeduh.c/
/* _______ ____ __ ___ ___ * \ _ \ \ / \ / \ \ / / ' ' ' * | | \ \ | | || | \/ | . . * | | | | | | || ||\ /| | * | | | | | | || || \/ | | ' ' ' * | | | | | | || || | | . . * | |_/ / \ \__// || | | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque * / \ * / . \ * makeduh.c - Function to construct a DUH from / / \ \ * its components. | < / \_ * | \/ /\ / * By entheh. \_ / > / * | \ / / * | ' / * \__/ */ #include <stdlib.h> #include <string.h> #include "dumb.h" #include "internal/dumb.h" static DUH_SIGNAL *make_signal(DUH_SIGTYPE_DESC *desc, sigdata_t *sigdata) { DUH_SIGNAL *signal; ASSERT((desc->start_sigrenderer && desc->end_sigrenderer) || (!desc->start_sigrenderer && !desc->end_sigrenderer)); ASSERT(desc->sigrenderer_generate_samples && desc->sigrenderer_get_current_sample); signal = malloc(sizeof(*signal)); if (!signal) { if (desc->unload_sigdata) if (sigdata) (*desc->unload_sigdata)(sigdata); return NULL; } signal->desc = desc; signal->sigdata = sigdata; return signal; } DUH *make_duh(dumb_off_t length, int n_tags, const char *const tags[][2], int n_signals, DUH_SIGTYPE_DESC *desc[], sigdata_t *sigdata[]) { DUH *duh = malloc(sizeof(*duh)); int i; int fail; if (duh) { duh->n_signals = n_signals; duh->signal = malloc(n_signals * sizeof(*duh->signal)); if (!duh->signal) { free(duh); duh = NULL; } } if (!duh) { for (i = 0; i < n_signals; i++) if (desc[i]->unload_sigdata) if (sigdata[i]) (*desc[i]->unload_sigdata)(sigdata[i]); return NULL; } duh->n_tags = 0; duh->tag = NULL; fail = 0; for (i = 0; i < n_signals; i++) { duh->signal[i] = make_signal(desc[i], sigdata[i]); if (!duh->signal[i]) fail = 1; } if (fail) { unload_duh(duh); return NULL; } duh->length = length; { int mem = n_tags * 2; /* account for NUL terminators here */ char *ptr; for (i = 0; i < n_tags; i++) mem += strlen(tags[i][0]) + strlen(tags[i][1]); if (mem <= 0) return duh; duh->tag = malloc(n_tags * sizeof(*duh->tag)); if (!duh->tag) return duh; duh->tag[0][0] = malloc(mem); if (!duh->tag[0][0]) { free(duh->tag); duh->tag = NULL; return duh; } duh->n_tags = n_tags; ptr = duh->tag[0][0]; for (i = 0; i < n_tags; i++) { duh->tag[i][0] = ptr; strcpy(ptr, tags[i][0]); ptr += strlen(tags[i][0]) + 1; duh->tag[i][1] = ptr; strcpy(ptr, tags[i][1]); ptr += strlen(tags[i][1]) + 1; } } return duh; } int duh_add_signal(DUH *duh, DUH_SIGTYPE_DESC *desc, sigdata_t *sigdata) { DUH_SIGNAL **signal; if (!duh || !desc || !sigdata) return -1; signal = (DUH_SIGNAL **)realloc(duh->signal, (duh->n_signals + 1) * sizeof(*duh->signal)); if (!signal) return -1; duh->signal = signal; memmove(signal + 1, signal, duh->n_signals * sizeof(*signal)); duh->n_signals++; signal[0] = make_signal(desc, sigdata); if (!signal[0]) return -1; return 0; }