From: <fea...@li...> - 2006-03-08 17:27:06
|
Revision: 57 Author: KoenTanghe Date: 2006-03-08 09:26:50 -0800 (Wed, 08 Mar 2006) ViewCVS: http://svn.sourceforge.net/feapi/?rev=57&view=rev Log Message: ----------- Added FEAPI_MaxMSP_Host and FEAPIExamplePluginFindRms files that were forgotten in the last merge. Added Paths: ----------- trunk/FEAPI/examples/host/FEAPI_MaxMSP_Host/ trunk/FEAPI/examples/host/FEAPI_MaxMSP_Host/feapi~.cpp trunk/FEAPI/examples/plugin/FEAPIExamplePluginFindRms/ trunk/FEAPI/examples/plugin/FEAPIExamplePluginFindRms/FEAPIExamplePluginFindRms.cpp trunk/FEAPI/examples/plugin/FEAPIExamplePluginFindRms/FEAPIExamplePluginFindRms.h Added: trunk/FEAPI/examples/host/FEAPI_MaxMSP_Host/feapi~.cpp =================================================================== --- trunk/FEAPI/examples/host/FEAPI_MaxMSP_Host/feapi~.cpp (rev 0) +++ trunk/FEAPI/examples/host/FEAPI_MaxMSP_Host/feapi~.cpp 2006-03-08 17:26:50 UTC (rev 57) @@ -0,0 +1,578 @@ +/*************************************************************************************** +* +* Copyright (C) 2006 by IRCAM-Centre Georges Pompidou, Paris, France. +* Author: Remy Muller +* +* FEAPI (Feature Extraction API) plugin host for Max/MSP +* +*/ + +//FEAPI +#include "FEAPI.h" +#include "FEAPIHostUtils.h" +#include "FEAPIPluginProxy.h" + +#define HOST_API_MAJOR_VERSION 1 + +//MaxMSP +#include "ext.h" +#include "z_dsp.h" +//#include "ext_obex.h" + +// std +#include <vector> +#include <string> +#include <stdexcept> +#include <cassert> +using std::vector; +using std::string; + +#undef min +#undef max + +typedef void Outlet; +typedef void Clock; + +typedef struct +{ + t_pxobject obj; + void *obex; + CFEAPIPluginProxy plugin; + + int numinputs; + int numoutputs; + int numparameters; + double sr; + vector< vector<float> > results; + vector<Outlet *> outlets; + Clock *clock; +} feapi_t; + +void *feapi_class; + +static const long maxsupportedinputs = 1024; +//---------------------------------------------------------------------- +static t_int * feapi_perform(t_int *w) +{ + feapi_t *self = (feapi_t *)(w[1]); + CFEAPIPluginProxy &plugin = self->plugin; + + const FEAPI_Signal_t *inputs[maxsupportedinputs]; + FEAPI_TimeStamp_t timestamps[maxsupportedinputs]; + + double time = 0.0; + //time = double(systime_ms()); // system time + clock_getftime(&time); // or logical time + + for(int i=0;( i<self->numinputs) && (i < maxsupportedinputs);i++) + { + // it only works because + // t_signal = FEAPI_Signal_t = float + // if max or FEAPI changes to double + // we'd have to use internal buffers and do the conversion manually + inputs[i] = (FEAPI_Signal_t *)w[2+i]; + timestamps[i] = time*1000.0; // time stamp in seconds + } + int size = (int)(w[self->numinputs+2]); + + //process + try + { + plugin.ProcessPlugin(inputs,timestamps,size); + + // scan in reverse order because max sends results from right to left + for(int i=plugin.GetPluginNumOfResults()-1; i>=0; --i) + { + int iSizeOfResult = plugin.GetPluginSizeOfResult(i); + + // TODO: change this, we are overwritting the results + // what if features are multidimmensional? + while(iSizeOfResult > 0) + { + if(iSizeOfResult > self->results[i].size()) + self->results[i].resize(iSizeOfResult); + + float *pfResults = &(self->results[i][0]); + plugin.GetPluginResult(i,pfResults,timestamps); + + iSizeOfResult = plugin.GetPluginSizeOfResult(i); + } + + //tmp solution output the first element + if(self->results[i].size() == 1) + outlet_float(self->outlets[i],double(self->results[i][0])); + else if(self->results[i].size() > 1) + { + t_atom atoms[1024]; // maybe not enough if we have an FFT as n-dimensional feature + // we should use an internal buffer of preallocated atoms which is resized if necessary + + for(int j=0; j < self->results[i].size();++j) + SETFLOAT(atoms+j,self->results[i][j]); + + outlet_anything(self->outlets[i], gensym("list"), 1, atoms); + } + } + + //structure timestamps and result in order to schedule outputs + // set alarm for output and reset trigger + /* + clock_fdelay(self->clock, 0.0); + self->trigger = 0; + */ + } + catch(...) + { + //post("exception: "); + } + return w + self->numinputs+2+1; +} + +//---------------------------------------------------------------------- +static void feapi_dsp(feapi_t *self, t_signal **sp, short *count) +{ + double sr = sp[0]->s_sr; + int n_tick = sp[0]->s_n; + + if(self->sr != sr) + { + self->sr = sr; + if(self->plugin.InitializePlugin(sr,self->numinputs,HOST_API_MAJOR_VERSION,NULL) != FEAPI_kNoError) + { + post("Initializing FEAPI plugin failed"); + post("Audio in won't be processed"); + return; + } + } + + //change that line + void *w[maxsupportedinputs]; // that should be enough + assert(self->numinputs < (maxsupportedinputs-1)); + + w[0] = self; + for(int i=0;i<self->numinputs;i++) + { + w[i+1] = sp[i]->s_vec; + } + w[self->numinputs+1] = (void *)n_tick; + + dsp_addv(feapi_perform, self->numinputs+2, w); +} + +/*************************************************************** +* +* user methods +* +*/ + +//---------------------------------------------------------------------- +static void feapi_getname(feapi_t *self) +{ + CFEAPIPluginProxy &plugin = self->plugin; + char text[FEAPI_uiMaxNameLength]; + memset(text,0,FEAPI_uiMaxNameLength); + plugin.GetPluginName(text); + + t_atom atoms[1]; + SETSYM(atoms,gensym(text)); + + outlet_anything(self->outlets.back(), gensym("name"), 1, atoms); +} + +//---------------------------------------------------------------------- +static void feapi_getid(feapi_t *self) +{ + CFEAPIPluginProxy &plugin = self->plugin; + char text[FEAPI_uiMaxNameLength]; + memset(text,0,FEAPI_uiMaxNameLength); + plugin.GetPluginId(text); + + t_atom atoms[1]; + SETSYM(atoms,gensym(text)); + outlet_anything(self->outlets.back(), gensym("id"), 1, atoms); +} + +//---------------------------------------------------------------------- +static void feapi_getcopyright(feapi_t *self) +{ + CFEAPIPluginProxy &plugin = self->plugin; + char text[FEAPI_uiMaxUnitLength]; + memset(text,0,FEAPI_uiMaxUnitLength); + plugin.GetPluginCopyright(text); + + t_atom atoms[1]; + SETSYM(atoms,gensym(text)); + outlet_anything(self->outlets.back(), gensym("copyright"), 1, atoms); +} + +//---------------------------------------------------------------------- +static void feapi_getdescription(feapi_t *self) +{ + CFEAPIPluginProxy &plugin = self->plugin; + char text[FEAPI_uiMaxDescriptionLength]; + memset(text,0,FEAPI_uiMaxDescriptionLength); + plugin.GetPluginDescription(text); + + t_atom atoms[1]; + SETSYM(atoms,gensym(text)); + outlet_anything(self->outlets.back(), gensym("description"), 1, atoms); +} + +//---------------------------------------------------------------------- +static void feapi_getvendor(feapi_t *self) +{ + CFEAPIPluginProxy &plugin = self->plugin; + char text[FEAPI_uiMaxNameLength]; + memset(text,0,FEAPI_uiMaxNameLength); + plugin.GetPluginVendor(text); + + t_atom atoms[1]; + SETSYM(atoms,gensym(text)); + outlet_anything(self->outlets.back(), gensym("vendor"), 1, atoms); +} + +//---------------------------------------------------------------------- +static void feapi_findplugins(feapi_t *self) +{ +} + +//---------------------------------------------------------------------- +static void feapi_getparaminfo(feapi_t *self,int i) +{ + CFEAPIPluginProxy &plugin = self->plugin; + + FEAPI_ParameterDescription_t description; + memset(description.acDescription,0,FEAPI_uiMaxDescriptionLength); + memset(description.acName,0,FEAPI_uiMaxNameLength); + memset(description.acUnit,0,FEAPI_uiMaxUnitLength); + + if(plugin.GetPluginParameterDescription(i,&description) != FEAPI_kNoError) + return; + + t_atom atoms[3]; + SETLONG(atoms,i); + SETSYM(atoms+1,gensym("min")); + SETFLOAT(atoms+2,description.fRangeMin); + outlet_anything(self->outlets.back(), gensym("paraminfo"), 3, atoms); + + SETLONG(atoms,i); + SETSYM(atoms+1,gensym("default")); + SETFLOAT(atoms+2,description.fDefaultValue); + outlet_anything(self->outlets.back(), gensym("paraminfo"), 3, atoms); + + SETLONG(atoms,i); + SETSYM(atoms+1,gensym("max")); + SETFLOAT(atoms+2,description.fRangeMax); + outlet_anything(self->outlets.back(), gensym("paraminfo"), 3, atoms); + + SETLONG(atoms,i); + SETSYM(atoms+1,gensym("name")); + SETSYM(atoms+2,gensym(description.acName)); + outlet_anything(self->outlets.back(), gensym("paraminfo"), 3, atoms); + + SETLONG(atoms,i); + SETSYM(atoms+1,gensym("unit")); + SETSYM(atoms+2,gensym(description.acUnit)); + outlet_anything(self->outlets.back(), gensym("paraminfo"), 3, atoms); + + + SETLONG(atoms,i); + SETSYM(atoms+1,gensym("description")); + SETSYM(atoms+2,gensym(description.acDescription)); + outlet_anything(self->outlets.back(), gensym("paraminfo"), 3, atoms); +} + +//---------------------------------------------------------------------- +static void feapi_getresultinfo(feapi_t *self,int i) +{ + CFEAPIPluginProxy &plugin = self->plugin; + + FEAPI_SignalDescription_t description; + memset(description.acDescription,0,FEAPI_uiMaxDescriptionLength); + memset(description.acName,0,FEAPI_uiMaxNameLength); + memset(description.acUnit,0,FEAPI_uiMaxUnitLength); + + if(plugin.GetPluginResultDescription(i,&description) != FEAPI_kNoError) + return; + + t_atom atoms[3]; + + SETLONG(atoms,i); + SETSYM(atoms+1,gensym("samplerate")); + SETFLOAT(atoms+2,description.fSampleRate); + outlet_anything(self->outlets.back(), gensym("resultinfo"), 3, atoms); + + SETLONG(atoms,i); + SETSYM(atoms+1,gensym("min")); + SETFLOAT(atoms+2,description.fRangeMin); + outlet_anything(self->outlets.back(), gensym("resultinfo"), 3, atoms); + + SETLONG(atoms,i); + SETSYM(atoms+1,gensym("max")); + SETFLOAT(atoms+2,description.fRangeMax); + outlet_anything(self->outlets.back(), gensym("resultinfo"), 3, atoms); + + SETLONG(atoms,i); + SETSYM(atoms+1,gensym("name")); + SETSYM(atoms+2,gensym(description.acName)); + outlet_anything(self->outlets.back(), gensym("resultinfo"), 3, atoms); + + SETLONG(atoms,i); + SETSYM(atoms+1,gensym("unit")); + SETSYM(atoms+2,gensym(description.acUnit)); + outlet_anything(self->outlets.back(), gensym("resultinfo"), 3, atoms); + + SETLONG(atoms,i); + SETSYM(atoms+1,gensym("description")); + SETSYM(atoms+2,gensym(description.acDescription)); + outlet_anything(self->outlets.back(), gensym("resultinfo"), 3, atoms); +} + +//---------------------------------------------------------------------- +static void feapi_getparam(feapi_t *self,int i) +{ + CFEAPIPluginProxy &plugin = self->plugin; + + float x = plugin.GetPluginParameter(i); + post("%f",x); + t_atom atoms[2]; + + SETLONG(atoms,i); + SETFLOAT(atoms+1,x); + outlet_anything(self->outlets.back(), gensym("param"), 2, atoms); +} + +//---------------------------------------------------------------------- +static void feapi_setparam(feapi_t *self,int i,float x) +{ + CFEAPIPluginProxy &plugin = self->plugin; + + // se should verify that the parameter is realtime or not + // and maybe scan for possible IO change. + // however max cannot resize the number of IO dynamically without user action. + + if(plugin.SetPluginParameter(i,x) == FEAPI_kNoError) + return; + else + return; +} + +//---------------------------------------------------------------------- +static void feapi_getnumparams(feapi_t *self) +{ + CFEAPIPluginProxy &plugin = self->plugin; + + long x = plugin.GetPluginNumOfParameters(); + t_atom atoms[1]; + + SETLONG(atoms,x); + outlet_anything(self->outlets.back(), gensym("numparams"), 1, atoms); +} + +//---------------------------------------------------------------------- +static void feapi_trigger(feapi_t *self) +{ +} + +//---------------------------------------------------------------------- +static void feapi_output(feapi_t *self) +{ + /* + int i; + + outlet_float(self->outlet2, self->quality); + outlet_float(self->outlet1, self->power); + outlet_float(self->outlet0, self->pitch); + */ +} + +//---------------------------------------------------------------------- +static void feapi_version(t_object *o, Symbol *s, short ac, Atom *at) +{ + post("feapi~ (Feature Extraction API host), version %s", "0.1"); + post(" by Remy Muller"); + post(" Copyright \xA9 2006 IRCAM - Centre Pompidou"); +} + +//---------------------------------------------------------------------- +static void feapi_print(feapi_t *self) +{ + post("feapi~"); +} + +static void loadplugin(feapi_t *self,const char *filename) +{ + CFEAPIPluginProxy &plugin = self->plugin; + + if(plugin.Load(filename) != FEAPI_kNoError) + throw std::runtime_error(string("can't load feapi plugin ")+string(filename)); + + int major = plugin.GetPluginAPIVersion(FEAPI_kMajorVersion); + int minor = plugin.GetPluginAPIVersion(FEAPI_kMinorVersion); + int build = plugin.GetPluginAPIVersion(FEAPI_kSubVersion); +#ifdef NDEBUG + post("FEAPI version %d.%d.%d",major,minor,build); +#endif + + if(plugin.Create() != FEAPI_kNoError) + throw std::runtime_error("can't instantiate feapi plugin"); + + char name[FEAPI_uiMaxNameLength]; + memset(name,0,FEAPI_uiMaxNameLength); + plugin.GetPluginName(name); +#ifdef NDEBUG + post(name); +#endif + float sr = sys_getsr(); + self->sr = sr; + + if(plugin.InitializePlugin(sr,self->numinputs,HOST_API_MAJOR_VERSION,NULL) != FEAPI_kNoError) + throw std::runtime_error("can't initialize feapi plugin"); + + self->numoutputs = plugin.GetPluginNumOfResults(); + self->numparameters = plugin.GetPluginNumOfParameters(); + + int minchannels = plugin.GetPluginProperty(FEAPI_kMinChannels); + int maxchannels = plugin.GetPluginProperty(FEAPI_kMaxChannels); + self->numinputs = std::max(std::min(self->numinputs,maxchannels),minchannels); + + self->results.resize(plugin.GetPluginNumOfResults()); + for(int i=0; i<plugin.GetPluginNumOfResults(); ++i) + self->results[i].reserve(64); // that should be enough to not allocate memory during processing +} + +/*************************************************************** +* +* class +* +*/ +static void *feapi_new(Symbol *s, short ac, Atom *at) +{ + feapi_t *self = (feapi_t *)newobject(feapi_class); +#ifdef WIN32 + string filename = "C:\\Program Files\\Fichiers communs\\Cycling '74\\externals\\feapi\\"; +#elif MAC + string filename = getenv("HOME"); + filename += "/Library/Audio/Plug-Ins/FEAPI/"; +#else + string filename = ""; +#endif + + self->numinputs = 1; + self->numoutputs = 0; + + switch(ac) + { + case 2: + if( at[1].a_type == A_LONG) + self->numinputs = at[1].a_w.w_long; + case 1: + if( at[0].a_type == A_SYM) + { + char * suffix= at[0].a_w.w_sym->s_name; + filename += suffix; + break; + } + default: + filename += "FindAbsoluteMax"; + break; + } + +#ifdef WIN32 + filename += ".dll"; +#elif MAC + filename += ".bundle"; +#else + // TODO: +#endif + + try + { + loadplugin(self,filename.c_str()); + } + catch(std::exception &e) + { + post(const_cast<char *>(e.what())); + return NULL; + } + + // DSP setup & inlets + dsp_setup((t_pxobject *)self, self->numinputs); + + // outlets + self->outlets.resize(self->numoutputs+1); + + self->outlets[self->numoutputs] = outlet_new((t_pxobject *)self,0L); // lastout for getting infos + + //for each outlet in reverse order + for(int i=self->numoutputs; i>0; i--) + { + self->outlets[i-1] = outlet_new((t_pxobject *)self,0L); // we'll be sending lists or float + } + + self->clock = clock_new(self,(method)feapi_output); + + return self; +} + +//---------------------------------------------------------------------- +static void feapi_free(feapi_t *self) +{ + freeobject((t_object *)self->clock); + + dsp_free((t_pxobject *)self); +} + +//---------------------------------------------------------------------- +void feapi_assist (feapi_t *self, void *box, long msg,long arg, char *dst) +{ + long maxsize = 64; + //long size = FEAPI_uiMaxNameLength; // max crashes with 1024 + + if (msg==ASSIST_INLET) + { + FEAPI_SignalDescription_t description; + self->plugin.GetPluginInputDescription(arg,&description); + strncpy(dst,description.acName,maxsize); + } + else if (msg==ASSIST_OUTLET) + { + FEAPI_SignalDescription_t description; + self->plugin.GetPluginResultDescription(arg,&description); + strncpy(dst,description.acName,maxsize); + } +} + +//---------------------------------------------------------------------- +int main(void) +{ + setup((t_messlist **)&feapi_class, (method)feapi_new, (method)feapi_free, (short)sizeof(feapi_t), 0, A_GIMME, 0); + + addmess((method)feapi_dsp, "dsp", A_CANT, 0); + + addmess((method)feapi_print, "print", 0); + addmess((method)feapi_version, "version", 0); + + // setter + addmess((method)feapi_setparam, "setparam", A_LONG, A_FLOAT,0); + + //getter + addmess((method)feapi_getparam, "getparam", A_LONG,0); + addmess((method)feapi_getparaminfo, "getparaminfo", A_LONG,0); + addmess((method)feapi_getresultinfo,"getresultinfo",A_LONG,0); + + addmess((method)feapi_getname, "getname", 0); + addmess((method)feapi_getid, "getid", 0); + addmess((method)feapi_getcopyright, "getcopyright", 0); + addmess((method)feapi_getdescription, "getdescription", 0); + addmess((method)feapi_getnumparams, "getnumparams", 0); + addmess((method)feapi_getvendor, "getvendor", 0); + + // methods + addmess((method)feapi_trigger, "bang", 0); + addmess((method)feapi_findplugins, "findplugins", 0); + addmess ((method)feapi_assist, "assist", A_CANT,0); + + dsp_initclass(); + + feapi_version(0, 0, 0, 0); +} Added: trunk/FEAPI/examples/plugin/FEAPIExamplePluginFindRms/FEAPIExamplePluginFindRms.cpp =================================================================== --- trunk/FEAPI/examples/plugin/FEAPIExamplePluginFindRms/FEAPIExamplePluginFindRms.cpp (rev 0) +++ trunk/FEAPI/examples/plugin/FEAPIExamplePluginFindRms/FEAPIExamplePluginFindRms.cpp 2006-03-08 17:26:50 UTC (rev 57) @@ -0,0 +1,342 @@ +//////////////////////////////////////////////////////////////////////////////////// +// /*! \file FEAPIExamplePluginFindMax.cpp: \brief implementation of the CFindAbsoluteMax class. */ +// +// Copyright (c) 2004-2005, Alexander Lerch, zplane.development GbR +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must link to the feapi website +// http://www.sf.net/projects/feapi, +// reproduce this list of conditions and the following +// disclaimer in the documentation and/or other materials +// provided with the distribution. +// * The name of the contributors to this software must not be used +// to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +//////////////////////////////////////////////////////////////////////////////////// +// CVS INFORMATION +// +// $RCSfile$ +// $Author: remymuller $ +// $Date: 2006-01-19 13:22:21 +0100 (do, 19 jan 2006) $ +// +// $Log$ +// Revision 1.1.2.1 2006/01/19 12:22:21 remymuller +// moved example into examples folder +// +// +//////////////////////////////////////////////////////////////////////////////////// + +#include <string> +#include <iostream> +#include <math.h> +#include <cstdlib> + +#include "FEAPI.h" +#include "FEAPIExamplePluginFindRms.h" + +#ifndef FLT_MAX +#define FLT_MAX 3.402823466e+38F +#endif + +// defines for plug in name etc. +#define _MY_PLUGIN_NAME "RmsFind" +#define _MY_PLUGIN_VENDOR "remy muller" +#define _MY_PLUGIN_DESCRIPTION "This PlugIn searches each input audio data block for its RMS value per channel" +#define _MY_PLUGIN_COPYRIGHT "(c) 2006 by remy muller" +#define _MY_PLUGIN_ID "RmsFindId" +#define _MY_NUM_PARAMETERS 0 // no parameters to adjust here.... + +// defines for description of result +#define _FEATURE_NAME "Rms Value" +#define _FEATURE_UNIT "dBFS" +#define _FEATURE_DESCRIPTION "The rms value of channel: %d per input block" +#define _FEATURE_RANGE_MIN -740 +#define _FEATURE_RANGE_MAX 0.0F +#define _FEATURE_QUANTIZED -1 // value is not quantized +#define _FEATURE_SAMPLERATE -1 // output sample rate equals input block length + + +CFindAbsoluteRms::CFindAbsoluteRms () : CFeatureExtractBase() +{ + // we have no special setting, so the number of parameters is zero in this case + m_iNumberOfParameters = _MY_NUM_PARAMETERS; + + // set of strings that will be returned by the default methods + m_cPluginName = _MY_PLUGIN_NAME; + m_cPluginVendor = _MY_PLUGIN_VENDOR; + m_cPluginDescription = _MY_PLUGIN_DESCRIPTION; + m_cPluginId = _MY_PLUGIN_ID; + m_cPluginCopyRight = _MY_PLUGIN_COPYRIGHT; + + // set plug in version info + m_iMajorVersion = 0x00000001; + m_iMinorVersion = 0x00000001; + m_iSubVersion = 0x00000000; + + m_pfRmsValue = 0; + m_pbIHaveResults = 0; +} + + +CFindAbsoluteRms::~CFindAbsoluteRms () +{ + // destroy feature vector + if (m_pfRmsValue) + delete [] m_pfRmsValue; + m_pfRmsValue = 0; + + // destroy bool vector + if (m_pbIHaveResults) + delete [] m_pbIHaveResults; + m_pbIHaveResults = 0; +} + + +FEAPI_Error_t CFindAbsoluteRms::InitializePlugin (float fInputSampleRate, + int iNumberOfAudioChannels, + int iHostApiMajorVersion, + FEAPI_UserData_t *pstUserData) +{ + CFeatureExtractBase::InitializePlugin ( fInputSampleRate, + iNumberOfAudioChannels, + iHostApiMajorVersion, + pstUserData); + + // note that in this special case, the number of results equals the number of channels, + // so we have to allocate it here: + m_iNumberOfResults = m_iNumberOfChannels; + + // allocate one dimensional result/feature vector + if (m_pfRmsValue) + delete m_pfRmsValue; + m_pfRmsValue = new float [m_iNumberOfResults]; + + // allocate one dimensional result/feature vector + if (m_pbIHaveResults) + delete m_pbIHaveResults; + m_pbIHaveResults = new bool [m_iNumberOfResults]; + + // initialize bool vector + for (int i = 0; i < m_iNumberOfResults; i++) + m_pbIHaveResults[i] = false; + + return FEAPI_kNoError; +} + + +FEAPI_Error_t CFindAbsoluteRms::GetPluginResultDescription (int iResultIndex, FEAPI_SignalDescription_t *pstResultDescription) +{ + // the description is for all results identical in this case + // only the channel number changes (channel number equals feature number for this plugin) + + if (iResultIndex >= m_iNumberOfResults) + return FEAPI_kUnspecifiedError; + + strcpy(pstResultDescription->acName, _FEATURE_NAME); + strcpy(pstResultDescription->acUnit, _FEATURE_UNIT); + sprintf(pstResultDescription->acDescription, _FEATURE_DESCRIPTION, iResultIndex); + pstResultDescription->fRangeMin = _FEATURE_RANGE_MIN; + pstResultDescription->fRangeMax = _FEATURE_RANGE_MAX; + pstResultDescription->fQuantizedTo = _FEATURE_QUANTIZED; + pstResultDescription->fSampleRate = _FEATURE_SAMPLERATE; + + return FEAPI_kNoError; +} + + +FEAPI_Error_t CFindAbsoluteRms::GetPluginInputDescription (int iInputIndex, FEAPI_SignalDescription_t *pstInputDescription) +{ + // the description is for all inputs identical in this case + // only the channel number changes (channel number equals feature number for this plugin) + + if (iInputIndex >= m_iNumberOfChannels) + return FEAPI_kUnspecifiedError; + + std::string tmp = "Channel: "; + char actmp[100] ; + //tmp.append (itoa(iInputIndex,actmp,10)); //itoa is not standard + sprintf(actmp,"%d",iInputIndex); + tmp.append(actmp); + tmp.copy (pstInputDescription->acName, FEAPI_uiMaxNameLength); + + tmp.erase (0, tmp.length ()); + tmp.copy (pstInputDescription->acUnit, FEAPI_uiMaxNameLength); + + tmp.erase (0, tmp.length ()); + strcpy (pstInputDescription->acDescription, pstInputDescription->acName); + + pstInputDescription->fRangeMin = -1; + pstInputDescription->fRangeMax = 1; + pstInputDescription->fQuantizedTo = -1; + pstInputDescription->fSampleRate = m_fSampleRate; + + return FEAPI_kNoError; +} + + +FEAPI_Error_t CFindAbsoluteRms::GetPluginParameterDescription (int iParameterIndex, FEAPI_ParameterDescription_t *pstParameterDescription) +{ + // we don't have any parameters in this plugin + return FEAPI_kUnknownError; +} + + +FEAPI_Error_t CFindAbsoluteRms::SetPluginParameter (int iParameterIndex, float fValue) +{ + // we don't have any parameters in this plugin + return FEAPI_kUnknownError; +} + + +float CFindAbsoluteRms::GetPluginParameter (int iParameterIndex) +{ + // we don't have any parameters in this plugin + return -1; +} + + +int CFindAbsoluteRms::GetPluginResultLatency (int iResultIndex) +{ + return 0; +} + + +FEAPI_Error_t CFindAbsoluteRms::ProcessPluginDone () +{ + // we don't have to do anything special here + return FEAPI_kNoError; +} + +FEAPI_Error_t CFindAbsoluteRms::ProcessPlugin (const float **ppfInputBuffer, const FEAPI_TimeStamp_t *ptTimeStamps, int iNumberOfFrames) +{ + if (!m_bIsInitialized) + return FEAPI_kUnspecifiedError; + + for (int iCh = 0; iCh < m_iNumberOfChannels; ++iCh) + { + m_pfRmsValue[iCh] = 0.0F; + float rms = 0.f; + for (int iIdx = 0; iIdx < iNumberOfFrames; ++iIdx) + { + const float x = ppfInputBuffer[iCh][iIdx]; + rms += x*x; + } + m_pfRmsValue[iCh] = sqrt(rms/float(iNumberOfFrames)); + m_pbIHaveResults[iCh] = true; + } + + return FEAPI_kNoError; +} + +int CFindAbsoluteRms::GetPluginSizeOfResult (int iResultIndex) +{ + if (iResultIndex >= m_iNumberOfResults) + return -1; + + if (m_pbIHaveResults[iResultIndex]) + return (sizeof(m_pfRmsValue[iResultIndex])/sizeof(float)); + else + return 0; +} + + +FEAPI_Error_t CFindAbsoluteRms::GetPluginResult (int iResultIndex, float *pfResult, FEAPI_TimeStamp_t *ptTimeStamp) +{ + if ((iResultIndex >= m_iNumberOfResults) || (!m_pbIHaveResults[iResultIndex])) + return FEAPI_kUnknownError; + + if (m_pfRmsValue[iResultIndex] < 1e-37) + m_pfRmsValue[iResultIndex] = 1e-37F; + *pfResult = 20*logf(m_pfRmsValue[iResultIndex])/logf(10.0F); + + m_pbIHaveResults[iResultIndex] = false; + + return FEAPI_kNoError; +} + + +FEAPI_Error_t CFindAbsoluteRms::ResetPlugin () +{ + for (int i = 0; i < m_iNumberOfResults; i++) + m_pfRmsValue[i] = 0.0F; + + return FEAPI_kNoError; +} + + +float CFindAbsoluteRms::GetPluginProperty ( FEAPI_PluginProperty_t ePluginProperty) +{ + switch (ePluginProperty) + { + case FEAPI_kMinSampleRate: + { + return 1; + } + case FEAPI_kMaxSampleRate: + { + return 1e38F; + } + case FEAPI_kMinChannels: + { + return 1; + } + case FEAPI_kMaxChannels: + { + return (1<<30)-1; + } + case FEAPI_kMinFrameSize: + { + return 1; + } + case FEAPI_kMaxFrameSize: + { + return (1<<30)-1; + } + case FEAPI_kOptFrameSize: + { + return (int)(0.01F * m_fSampleRate + .5F); + } + default: + { + // this shall never happen ... + return -1; + } + } + return -1; +} + +/////////////////////////////////////// +// entry points +#include "FEAPIEntryPoints.h" + +#ifdef __cplusplus +extern "C" { +#endif + +FEAPI_ENTRY_POINTS(CFindAbsoluteRms) + +#ifdef __cplusplus +} +#endif +/////////////////////////////////////// + Added: trunk/FEAPI/examples/plugin/FEAPIExamplePluginFindRms/FEAPIExamplePluginFindRms.h =================================================================== --- trunk/FEAPI/examples/plugin/FEAPIExamplePluginFindRms/FEAPIExamplePluginFindRms.h (rev 0) +++ trunk/FEAPI/examples/plugin/FEAPIExamplePluginFindRms/FEAPIExamplePluginFindRms.h 2006-03-08 17:26:50 UTC (rev 57) @@ -0,0 +1,131 @@ +//////////////////////////////////////////////////////////////////////////////////// +// /*! \file FEAPIExamplePluginFindMax.h: \brief interface of the CFindAbsoluteMax class. */ +// +// Copyright (c) 2004-2005, Alexander Lerch, zplane.development GbR +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must link to the feapi website +// http://www.sf.net/projects/feapi, +// reproduce this list of conditions and the following +// disclaimer in the documentation and/or other materials +// provided with the distribution. +// * The name of the contributors to this software must not be used +// to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +//////////////////////////////////////////////////////////////////////////////////// +// CVS INFORMATION +// +// $RCSfile$ +// $Author: remymuller $ +// $Date: 2006-01-19 13:22:21 +0100 (do, 19 jan 2006) $ +// +// $Log$ +// Revision 1.1.2.1 2006/01/19 12:22:21 remymuller +// moved example into examples folder +// +// +//////////////////////////////////////////////////////////////////////////////////// + +#if !defined(FIND_RMS_HEADER_INCLUDED__) +#define FIND_RMS_HEADER_INCLUDED__ + + +#include "FEAPIPluginBase.h" + +/*! +the class ::CFindAbsoluteMax is an example class to demonstrate how to implement +a plug-in for the Feature Extraction API. The functionality of this plug-in is to find +the absolute maximum value per audio channel for each input block and return the two +results in dBFS. + +*/ +class CFindAbsoluteRms : public CFeatureExtractBase +{ +public: + + CFindAbsoluteRms (); + + virtual ~CFindAbsoluteRms (); + + + //////////////////////////////////////////////////////////////////////////////////////// + // method declaration + // if you do not intend to use some of these functions, just delete them and the default + // values will be returned + + FEAPI_Error_t GetPluginResultDescription ( int iResultIndex, + FEAPI_SignalDescription_t *pstResultDescription); + + FEAPI_Error_t GetPluginInputDescription ( int iInputIndex, + FEAPI_SignalDescription_t *pstInputDescription); + + FEAPI_Error_t GetPluginParameterDescription ( int iParameterIndex, + FEAPI_ParameterDescription_t *pstParameterDescription); + + FEAPI_Error_t SetPluginParameter ( int iParameterIndex, + float fValue); + + float GetPluginParameter ( int iParameterIndex); + + + int GetPluginResultLatency (int iResultIndex); + + float GetPluginProperty ( FEAPI_PluginProperty_t ePluginProperty); + + FEAPI_Error_t InitializePlugin ( float fInputSampleRate, + int iNumberOfAudioChannels, + int iHostApiMajorVersion, + FEAPI_UserData_t *pstUserData); + + FEAPI_Error_t ProcessPlugin ( const float **ppfInputBuffer, + const FEAPI_TimeStamp_t *ptFEAPI_TimeStamp, + int iNumberOfFrames); + + FEAPI_Error_t ProcessPluginDone (); + + + int GetPluginSizeOfResult (int iResultIndex); + + FEAPI_Error_t GetPluginResult ( int iResultIndex, + float *pfResult, + FEAPI_TimeStamp_t *ptFEAPI_TimeStamp); + + FEAPI_Error_t ResetPlugin (); + +private: + + // remove and add variables acc. your needs + FEAPI_SignalDescription_t m_stResultDescription; + + // this buffer will contain the maximum value per call + float *m_pfRmsValue; + + // this bool will signal if a result is available + bool *m_pbIHaveResults; + +}; + +#endif // #if !defined(FIND_ABSOLUTE_MAX_HEADER_INCLUDED__) + + + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |