af_ladspa.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 971 行 · 第 1/3 页
C
971 行
int p = setup->inputcontrolsmap[i]; LADSPA_PortRangeHint hint = setup->plugin_descriptor->PortRangeHints[p]; val = setup->inputcontrols[p]; if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor) && val < hint.LowerBound) { af_msg(AF_MSG_ERROR, MSGTR_AF_LADSPA_ErrControlBelow, setup->myname, i, hint.LowerBound); return AF_ERROR; } if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) && val > hint.UpperBound) { af_msg(AF_MSG_ERROR, MSGTR_AF_LADSPA_ErrControlAbove, setup->myname, i, hint.UpperBound); return AF_ERROR; } } af_msg(AF_MSG_VERBOSE, "%s: all controls have sane values\n", setup->myname); /* All is well! */ setup->status = AF_OK; return AF_OK; } } return AF_UNKNOWN;}/* ------------------------------------------------------------------------- *//** \brief Uninitialise the LADSPA Plugin Loader filter. * * This function deactivates the plugin(s), cleans up, frees all allocated * memory and exits. * * \return No return value. */static void uninit(struct af_instance_s *af) { int i; if (af->data) free(af->data); if (af->setup) { af_ladspa_t *setup = (af_ladspa_t*) af->setup; const LADSPA_Descriptor *pdes = setup->plugin_descriptor; if (setup->myname) { af_msg(AF_MSG_VERBOSE, "%s: cleaning up\n", setup->myname); free(setup->myname); } if (setup->chhandles) { for(i=0; i<setup->nch; i+=setup->ninputs) { if (pdes->deactivate) pdes->deactivate(setup->chhandles[i]); if (pdes->cleanup) pdes->cleanup(setup->chhandles[i]); } free(setup->chhandles); } if (setup->file) free(setup->file); if (setup->label) free(setup->label); if (setup->inputcontrolsmap) free(setup->inputcontrolsmap); if (setup->inputcontrols) free(setup->inputcontrols); if (setup->outputcontrolsmap) free(setup->outputcontrolsmap); if (setup->outputcontrols) free(setup->outputcontrols); if (setup->inputs) free(setup->inputs); if (setup->outputs) free(setup->outputs); if (setup->inbufs) { for(i=0; i<setup->nch; i++) { if (setup->inbufs[i]) free(setup->inbufs[i]); } free(setup->inbufs); } if (setup->outbufs) { for(i=0; i<setup->nch; i++) { if (setup->outbufs[i]) free(setup->outbufs[i]); } free(setup->outbufs); } if (setup->libhandle) dlclose(setup->libhandle); free(setup); setup = NULL; }}/* ------------------------------------------------------------------------- *//** \brief Process chunk of audio data through the selected LADSPA Plugin. * * \param af Pointer to audio filter instance * \param data Pointer to chunk of audio data * * \return Either AF_ERROR or AF_OK */static af_data_t* play(struct af_instance_s *af, af_data_t *data) { af_ladspa_t *setup = af->setup; const LADSPA_Descriptor *pdes = setup->plugin_descriptor; float *audio = (float*)data->audio; int nsamples = data->len/4; /* /4 because it's 32-bit float */ int nch = data->nch; int rate = data->rate; int i, p; if (setup->status !=AF_OK) return data; /* See if it's the first call. If so, setup inbufs/outbufs, instantiate * plugin, connect ports and activate plugin */ /* 2004-12-07: Also check if the buffersize has to be changed! * data->len is not constant per se! re-init buffers. */ if ( (setup->bufsize != nsamples/nch) || (setup->nch != nch) ) { /* if setup->nch==0, it's the first call, if not, something has * changed and all previous mallocs have to be freed */ if (setup->nch != 0) { af_msg(AF_MSG_DEBUG1, "%s: bufsize change; free old buffer\n", setup->myname); if(setup->inbufs) { for(i=0; i<setup->nch; i++) { if(setup->inbufs[i]) free(setup->inbufs[i]); } free(setup->inbufs); } if(setup->outbufs) { for(i=0; i<setup->nch; i++) { if(setup->outbufs[i]) free(setup->outbufs[i]); } free(setup->outbufs); } } /* everything is freed */ setup->bufsize = nsamples/nch; setup->nch = nch; setup->inbufs = calloc(nch, sizeof(float*)); setup->outbufs = calloc(nch, sizeof(float*)); af_msg(AF_MSG_DEBUG1, "%s: bufsize = %d\n", setup->myname, setup->bufsize); for(i=0; i<nch; i++) { setup->inbufs[i] = calloc(setup->bufsize, sizeof(float)); setup->outbufs[i] = calloc(setup->bufsize, sizeof(float)); } /* only on the first call, there are no handles. */ if (!setup->chhandles) { setup->chhandles = calloc(nch, sizeof(LADSPA_Handle)); /* create handles * for stereo effects, create one handle for two channels */ for(i=0; i<nch; i++) { if (i % setup->ninputs) { /* stereo effect */ /* copy the handle from previous channel */ setup->chhandles[i] = setup->chhandles[i-1]; continue; } setup->chhandles[i] = pdes->instantiate(pdes, rate); } } /* connect input/output ports for each channel/filter instance * * always (re)connect ports */ for(i=0; i<nch; i++) { pdes->connect_port(setup->chhandles[i], setup->inputs[i % setup->ninputs], setup->inbufs[i]); pdes->connect_port(setup->chhandles[i], setup->outputs[i % setup->ninputs], setup->outbufs[i]); /* connect (input) controls */ for (p=0; p<setup->nports; p++) { LADSPA_PortDescriptor d = pdes->PortDescriptors[p]; if (LADSPA_IS_PORT_CONTROL(d)) { if (LADSPA_IS_PORT_INPUT(d)) { pdes->connect_port(setup->chhandles[i], p, &(setup->inputcontrols[p]) ); } else { pdes->connect_port(setup->chhandles[i], p, &(setup->outputcontrols[p]) ); } } } /* Activate filter (if it isn't already :) ) */ if ( (pdes->activate) && (setup->activated == 0) ) { pdes->activate(setup->chhandles[i]); setup->activated = 1; } } /* All channels/filters done! except for... */ /* Stereo effect with one channel left. Use same buffer for left * and right. connect it to the second port. */ for (p = i; p % setup->ninputs; p++) { pdes->connect_port(setup->chhandles[i-1], setup->inputs[p % setup->ninputs], setup->inbufs[i-1]); pdes->connect_port(setup->chhandles[i-1], setup->outputs[p % setup->ninputs], setup->outbufs[i-1]); } /* done! */ } /* setup for first call/change of bufsize is done. * normal playing routine follows... */ /* Right now, I use a separate input and output buffer. * I could change this to in-place processing (inbuf==outbuf), but some * ladspa filters are broken and are not able to handle that. This seems * fast enough, so unless somebody complains, it stays this way :) */ /* Fill inbufs */ for (p=0; p<setup->bufsize; p++) { for (i=0; i<nch; i++) { setup->inbufs[i][p] = audio[p*nch + i]; } } /* Run filter(s) */ for (i=0; i<nch; i+=setup->ninputs) { pdes->run(setup->chhandles[i], setup->bufsize); } /* Extract outbufs */ for (p=0; p<setup->bufsize; p++) { for (i=0; i<nch; i++) { audio[p*nch + i] = setup->outbufs[i][p]; } } /* done */ return data;}/* ------------------------------------------------------------------------- *//** \brief Open LADSPA Plugin Loader Filter * * \param af Audio Filter instance * * \return Either AF_ERROR or AF_OK */static int af_open(af_instance_t *af) { af->control=control; af->uninit=uninit; af->play=play; af->mul.n=1; af->mul.d=1; af->data = calloc(1, sizeof(af_data_t)); if (af->data == NULL) return af_ladspa_malloc_failed((char*)af_info_ladspa.name); af->setup = calloc(1, sizeof(af_ladspa_t)); if (af->setup == NULL) { free(af->data); af->data=NULL; return af_ladspa_malloc_failed((char*)af_info_ladspa.name); } ((af_ladspa_t*)af->setup)->status = AF_ERROR; /* will be set to AF_OK if * all went OK and play() * should proceed. */ ((af_ladspa_t*)af->setup)->myname = strdup(af_info_ladspa.name); if (!((af_ladspa_t*)af->setup)->myname) return af_ladspa_malloc_failed((char*)af_info_ladspa.name); return AF_OK;}/* ------------------------------------------------------------------------- */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?