242 lines · 6.8 KB · C
RawDownload
/*  _______         ____    __         ___    ___ * \    _  \       \    /  \  /       \   \  /   /       '   '  ' *  |  | \  \       |  |    ||         |   \/   |         .      . *  |  |  |  |      |  |    ||         ||\  /|  | *  |  |  |  |      |  |    ||         || \/ |  |         '  '  ' *  |  |  |  |      |  |    ||         ||    |  |         .      . *  |  |_/  /        \  \__//          ||    |  | * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque *                                                      /  \ *                                                     / .  \ * rendsig.c - Wrappers to render samples from        / / \  \ *             the signals in a DUH.                 | <  /   \_ *                                                   |  \/ /\   / * By entheh.                                         \_  /  > / *                                                      | \ / / *                                                      |  ' / *                                                       \__/ */ #include <stdlib.h> #include "dumb.h"#include "internal/dumb.h" struct DUH_SIGRENDERER {    DUH_SIGTYPE_DESC *desc;     sigrenderer_t *sigrenderer;     int n_channels;     long pos;    int subpos;     DUH_SIGRENDERER_SAMPLE_ANALYSER_CALLBACK callback;    void *callback_data;}; DUH_SIGRENDERER *duh_start_sigrenderer(DUH *duh, int sig, int n_channels,                                       long pos) {    DUH_SIGRENDERER *sigrenderer;     DUH_SIGNAL *signal;    DUH_START_SIGRENDERER proc;     if (!duh)        return NULL;     if ((unsigned int)sig >= (unsigned int)duh->n_signals)        return NULL;     signal = duh->signal[sig];    if (!signal)        return NULL;     sigrenderer = malloc(sizeof(*sigrenderer));    if (!sigrenderer)        return NULL;     sigrenderer->desc = signal->desc;     proc = sigrenderer->desc->start_sigrenderer;     if (proc) {        duh->signal[sig] = NULL;        sigrenderer->sigrenderer =            (*proc)(duh, signal->sigdata, n_channels, pos);        duh->signal[sig] = signal;         if (!sigrenderer->sigrenderer) {            free(sigrenderer);            return NULL;        }    } else        sigrenderer->sigrenderer = NULL;     sigrenderer->n_channels = n_channels;     sigrenderer->pos = pos;    sigrenderer->subpos = 0;     sigrenderer->callback = NULL;     return sigrenderer;} void duh_sigrenderer_set_sample_analyser_callback(    DUH_SIGRENDERER *sigrenderer,    DUH_SIGRENDERER_SAMPLE_ANALYSER_CALLBACK callback, void *data) {    if (sigrenderer) {        sigrenderer->callback = callback;        sigrenderer->callback_data = data;    }} int duh_sigrenderer_get_n_channels(DUH_SIGRENDERER *sigrenderer) {    return sigrenderer ? sigrenderer->n_channels : 0;} long duh_sigrenderer_get_position(DUH_SIGRENDERER *sigrenderer) {    DUH_SIGRENDERER_GET_POSITION proc;     if (!sigrenderer)        return -1;     proc = sigrenderer->desc->sigrenderer_get_position;    if (proc)        return (*proc)(sigrenderer->sigrenderer);    else        return sigrenderer->pos;} void duh_sigrenderer_set_sigparam(DUH_SIGRENDERER *sigrenderer,                                  unsigned char id, long value) {    DUH_SIGRENDERER_SET_SIGPARAM proc;     if (!sigrenderer)        return;     proc = sigrenderer->desc->sigrenderer_set_sigparam;    if (proc)        (*proc)(sigrenderer->sigrenderer, id, value);    else        TRACE("Parameter #%d = %ld for signal %c%c%c%c, which does not take "              "parameters.\n",              (int)id, value, (int)(sigrenderer->desc->type >> 24),              (int)(sigrenderer->desc->type >> 16),              (int)(sigrenderer->desc->type >> 8),              (int)(sigrenderer->desc->type));} long duh_sigrenderer_generate_samples(DUH_SIGRENDERER *sigrenderer,                                      float volume, float delta, long size,                                      sample_t **samples) {    long rendered;    LONG_LONG t;     if (!sigrenderer)        return 0;     rendered = (*sigrenderer->desc->sigrenderer_generate_samples)(        sigrenderer->sigrenderer, volume, delta, size, samples);     if (rendered) {        if (sigrenderer->callback)            (*sigrenderer->callback)(sigrenderer->callback_data,                                     (const sample_t *const *)samples,                                     sigrenderer->n_channels, rendered);         t = sigrenderer->subpos + (LONG_LONG)(delta * 65536.0 + 0.5) * rendered;         sigrenderer->pos += (long)(t >> 16);        sigrenderer->subpos = (int)t & 65535;    }     return rendered;} void duh_sigrenderer_get_current_sample(DUH_SIGRENDERER *sigrenderer,                                        float volume, sample_t *samples) {    if (sigrenderer)        (*sigrenderer->desc->sigrenderer_get_current_sample)(            sigrenderer->sigrenderer, volume, samples);} void duh_end_sigrenderer(DUH_SIGRENDERER *sigrenderer) {    if (sigrenderer) {        if (sigrenderer->desc->end_sigrenderer)            if (sigrenderer->sigrenderer)                (*sigrenderer->desc->end_sigrenderer)(sigrenderer->sigrenderer);         free(sigrenderer);    }} DUH_SIGRENDERER *duh_encapsulate_raw_sigrenderer(sigrenderer_t *vsigrenderer,                                                 DUH_SIGTYPE_DESC *desc,                                                 int n_channels, long pos) {    DUH_SIGRENDERER *sigrenderer;     if (desc->start_sigrenderer && !vsigrenderer)        return NULL;     sigrenderer = malloc(sizeof(*sigrenderer));    if (!sigrenderer) {        if (desc->end_sigrenderer)            if (vsigrenderer)                (*desc->end_sigrenderer)(vsigrenderer);        return NULL;    }     sigrenderer->desc = desc;    sigrenderer->sigrenderer = vsigrenderer;     sigrenderer->n_channels = n_channels;     sigrenderer->pos = pos;    sigrenderer->subpos = 0;     sigrenderer->callback = NULL;     return sigrenderer;} sigrenderer_t *duh_get_raw_sigrenderer(DUH_SIGRENDERER *sigrenderer,                                       long type) {    if (sigrenderer && sigrenderer->desc->type == type)        return sigrenderer->sigrenderer;     return NULL;} #if 0// This function is disabled because we don't know whether we want to destroy// the sigrenderer if the type doesn't match. We don't even know if we need// the function at all. Who would want to keep an IT_SIGRENDERER (for// instance) without keeping the DUH_SIGRENDERER?sigrenderer_t *duh_decompose_to_raw_sigrenderer(DUH_SIGRENDERER *sigrenderer, long type){	if (sigrenderer && sigrenderer->desc->type == type) {   	if (sigrenderer) {		if (sigrenderer->desc->end_sigrenderer)			if (sigrenderer->sigrenderer)				(*sigrenderer->desc->end_sigrenderer)(sigrenderer->sigrenderer); 		free(sigrenderer);	}      		return sigrenderer->sigrenderer;	} 	return NULL;}#endif

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t