Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

FEAPIExamplePluginZeroCrossings.cpp

Go to the documentation of this file.
00001 
00002 //     /*! \file FEAPIExamplePluginZeroCrossings.cpp: \brief implementation of the CZeroCrossings class. */
00003 //
00004 //        Copyright (c) 2005-2007, Alexander Lerch, zplane.development GbR
00005 //        All rights reserved.
00006 //
00007 //        Redistribution and use in source and binary forms, with or without 
00008 //        modification, are permitted provided that the following conditions 
00009 //        are met:
00010 //
00011 //        *   Redistributions of source code must retain the above copyright 
00012 //            notice, this list of conditions and the following disclaimer. 
00013 //        *   Redistributions in binary form must reproduce the above 
00014 //            copyright notice, this list of conditions and the following 
00015 //            disclaimer in the documentation and/or other materials 
00016 //            provided with the distribution. 
00017 //        *   Neither the name of the FEAPI development team nor the names 
00018 //            of its contributors may be used to endorse or promote products 
00019 //            derived from this software without specific prior written 
00020 //            permission. 
00021 //
00022 //        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00023 //        "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
00024 //        LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
00025 //        FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
00026 //        COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
00027 //        INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
00028 //        BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
00029 //        LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
00030 //        CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00031 //        LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
00032 //        ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
00033 //        POSSIBILITY OF SUCH DAMAGE.
00034 //
00035 //
00037 
00038 
00039 
00040 #include <string>
00041 #include <iostream>
00042 #include <math.h>
00043 
00044 #include "zplVecLib.h"
00045 
00046 #include "FEAPI.h"
00047 #include "FEAPIExamplePluginZeroCrossings.h"
00048 #include "FEAPIEntryPoints.h"
00049 
00050 #ifndef FLT_MAX
00051 #define FLT_MAX 3.402823466e+38F
00052 #endif
00053 
00054 #define kDefaultNumOfResults    8
00055 
00057 #define _MY_MAJOR_VERSION       0x00000000
00058 #define _MY_MINOR_VERSION       0x00000000
00059 #define _MY_SUB_VERSION         0x00000001
00060 
00061 
00062 // defines for plug in name etc.
00063 #define _MY_PLUGIN_NAME        "ZeroCrossings"
00064 #define _MY_PLUGIN_VENDOR      "zplane.development"
00065 #define _MY_PLUGIN_DESCRIPTION "This PlugIn calculates the relative number of zero crossings per channel. A zero crossing is a sign change of two neibourghed samples."
00066 #define _MY_PLUGIN_COPYRIGHT   "(c) 2005 by zplane.development"
00067 #define _MY_PLUGIN_ID          "zplZeroCrossings"
00068 
00069 
00070 // defines for description of result
00071 #define kFeatureIndex          0
00072 #define kFeatureName           "Relative number of Zero-Crossings"
00073 #define kFeatureUnit           "-"
00074 #define kFeatureDescription    "The number of zero crossings in the analysis block divided by the analysis block length"
00075 #define kFeatureRangeMin       0.0F
00076 #define kFeatureRangeMax       1.0F
00077 #define kFeatureIsQuantized    -1  // value is not quantized
00078 
00079 #define kParam1Index                    0
00080 #define kParam1Name                     "Analysis Block Length"
00081 #define kParam1Unit                     "Frames"
00082 #define kParam1Description              "Length of analysis window for one result"
00083 #define kParam1RangeMin                 4
00084 #define kParam1RangeMax                 (float)((1<<30)-1)
00085 #define kParam1DefaultValue             1024
00086 #define kParam1QuantizedTo              4
00087 #define kParam1IsChangeableInRealTime   false
00088 
00089 #define kParam2Index                    1
00090 #define kParam2Name                     "Analysis Hop-Size"
00091 #define kParam2Unit                     "ms"
00092 #define kParam2Description              "Distance between two analysis block beginnings"
00093 #define kParam2RangeMin                 1
00094 #define kParam2RangeMax                 (float)((1<<30)-1)
00095 #define kParam2DefaultValue             10
00096 #define kParam2QuantizedTo              -1
00097 #define kParam2IsChangeableInRealTime   false
00098 
00099 #define kParam3Index                    2
00100 #define kParam3Name                     "Individual Channels or Sum Channel"
00101 #define kParam3Unit                     ""
00102 #define kParam3Description              "Determines wether the calculation should be done on the sum of all input channels ('0') or on each individual channel ('1')"
00103 #define kParam3RangeMin                 0
00104 #define kParam3RangeMax                 1
00105 #define kParam3DefaultValue             0
00106 #define kParam3QuantizedTo              1
00107 #define kParam3IsChangeableInRealTime   false
00108 
00109 enum MyParameters_t
00110 {
00111     kBlockSize      = 0,
00112     kHopSize        = 1,
00113     kChannelMode    = 2,
00114 
00115     kNumParameters
00116 };
00117 
00118 CZeroCrossings::CZeroCrossings () : CFeatureExtractBase()
00119 {
00120 
00121     zplVecLibDispatcher ();
00122     
00123     m_ppCRingBuffer         = 0;
00124     m_ppResults             = 0;
00125     m_pfProcessBuffer       = 0;
00126     m_ptLocalTimeStamp      = 0;
00127 
00128     m_iSizeOfResultBuffer   = kDefaultNumOfResults;
00129 
00130     // set strings that will be returned by the default methods
00131     m_cPluginName           = _MY_PLUGIN_NAME;
00132     m_cPluginVendor         = _MY_PLUGIN_VENDOR;
00133     m_cPluginDescription    = _MY_PLUGIN_DESCRIPTION;
00134     m_cPluginId             = _MY_PLUGIN_ID;
00135     m_cPluginCopyRight      = _MY_PLUGIN_COPYRIGHT;
00136 
00137     // set plug in version info
00138     m_iMajorVersion         = _MY_MAJOR_VERSION;
00139     m_iMinorVersion         = _MY_MINOR_VERSION;
00140     m_iSubVersion           = _MY_SUB_VERSION;
00141 
00142     m_afParameters[kBlockSize]  = kParam1DefaultValue;
00143     m_afParameters[kHopSize]    = kParam2DefaultValue;
00144     m_afParameters[kChannelMode]= kParam3DefaultValue;
00145 }
00146 
00147 
00148 CZeroCrossings::~CZeroCrossings ()
00149 {
00150     int iCh;
00151     if (m_ppCRingBuffer)
00152     {
00153         for (iCh = 0; iCh < this->GetPluginNumOfInputs (); iCh++)
00154         {
00155             if (m_ppCRingBuffer[iCh])
00156                 delete m_ppCRingBuffer[iCh];
00157             m_ppCRingBuffer[iCh]    = 0;
00158         }
00159         delete [] m_ppCRingBuffer;
00160         m_ppCRingBuffer     = 0;
00161     }
00162     if (m_ppResults)
00163     {
00164         for (iCh = 0; iCh < this->GetPluginNumOfResults (); iCh++)
00165         {
00166             if (m_ppResults[iCh])
00167                 delete [] m_ppResults[iCh];
00168             m_ppResults[iCh]        = 0;
00169         }
00170         delete [] m_ppResults;
00171         m_ppResults         = 0;
00172     }
00173     if (m_ptLocalTimeStamp)
00174         delete [] m_ptLocalTimeStamp;
00175     m_ptLocalTimeStamp  = 0;
00176 
00177     zplfFree (m_pfProcessBuffer);
00178 }
00179 
00180 
00181 FEAPI_Error_t      CZeroCrossings::InitializePlugin (   float               fInputSampleRate, 
00182                                                         int                 iNumberOfAudioChannels,
00183                                                         int                 iHostApiMajorVersion,
00184                                                         FEAPI_UserData_t     *pstUserData)
00185 {
00186     FEAPI_Error_t   rErr;
00187     int             iCh;
00188 
00189     // free already allocated memory
00190     if (m_ppCRingBuffer)
00191     {
00192         for (iCh = 0; iCh < this->GetPluginNumOfInputs (); iCh++)
00193         {
00194             if (m_ppCRingBuffer[iCh])
00195                 delete m_ppCRingBuffer[iCh];
00196             m_ppCRingBuffer[iCh]    = 0;
00197         }
00198         delete [] m_ppCRingBuffer;
00199         m_ppCRingBuffer     = 0;
00200     }
00201     if (m_ppResults)
00202     {
00203         for (iCh = 0; iCh < this->GetPluginNumOfResults (); iCh++)
00204         {
00205             if (m_ppResults[iCh])
00206                 delete [] m_ppResults[iCh];
00207             m_ppResults[iCh]        = 0;
00208         }
00209         delete [] m_ppResults;
00210         m_ppResults         = 0;
00211     }
00212     if (m_ptLocalTimeStamp)
00213         delete [] m_ptLocalTimeStamp;
00214     m_ptLocalTimeStamp  = 0;
00215     zplfFree (m_pfProcessBuffer);
00216 
00217     rErr    = CFeatureExtractBase::InitializePlugin (   fInputSampleRate, 
00218                                                         iNumberOfAudioChannels,
00219                                                         iHostApiMajorVersion,
00220                                                         pstUserData);
00221 
00222 
00223     if (rErr != FEAPI_kNoError)
00224         return rErr;
00225 
00226     // Set information about the plugin inputs
00227     char acChannelStr[FEAPI_kMaxDescriptionLength];
00228     for (iCh = 0; iCh < iNumberOfAudioChannels; ++iCh) {
00229         sprintf(acChannelStr, "Channel: %d", iCh);
00230         SetPluginInputPinInfo(CPin::SetIndex(iCh)
00231             .SetName(acChannelStr)
00232             .SetUnit("")
00233             .SetDescription(acChannelStr)
00234             .SetRangeMin(-1.0f)
00235             .SetRangeMax(1.0f)
00236             .SetSampleRate(fInputSampleRate)
00237         );
00238     }
00239         
00240     // Set information about the plugin results
00241     //m_iNumberOfResults              = (m_afParameters[kChannelMode] == 0) ? 1 : m_iNumberOfChannels;
00242     if (m_afParameters[kChannelMode] == 0)
00243     {
00244         SetPluginResultPinInfo(CPin::SetIndex(kFeatureIndex)
00245         .SetName(kFeatureName)
00246         .SetUnit(kFeatureUnit)
00247         .SetDescription(kFeatureDescription)
00248         .SetRangeMin(kFeatureRangeMin)
00249         .SetRangeMax(kFeatureRangeMax)
00250         .SetQuantizedTo(kFeatureIsQuantized)
00251         .SetSampleRate(1000.0F / m_afParameters[kHopSize])
00252     );
00253     }
00254     else
00255     {
00256         for (iCh = 0; iCh < iNumberOfAudioChannels; ++iCh) 
00257         {
00258             sprintf(acChannelStr, "%s Channel: %d", kFeatureName, iCh);
00259             SetPluginInputPinInfo(CPin::SetIndex(iCh)
00260                 .SetName(acChannelStr)
00261                 .SetUnit(kFeatureUnit)
00262                 .SetDescription(kFeatureDescription)
00263                 .SetRangeMin(kFeatureRangeMin)
00264                 .SetRangeMax(kFeatureRangeMax)
00265                 .SetSampleRate(1000.0F / m_afParameters[kHopSize])
00266                 );
00267         }
00268     }
00269 
00270     // Setting information about the plugin parameters
00271     SetPluginParameterPinInfo(CPin::SetIndex(kParam1Index)
00272         .SetName(kParam1Name)
00273         .SetUnit(kParam1Unit)
00274         .SetDescription(kParam1Description)
00275         .SetRangeMin(kParam1RangeMin)
00276         .SetRangeMax(kParam1RangeMax)
00277         .SetDefaultValue(kParam1DefaultValue)
00278         .SetQuantizedTo(kParam1QuantizedTo)
00279         .SetIsChangeableInRealTime(kParam1IsChangeableInRealTime)
00280     );
00281 
00282     SetPluginParameterPinInfo(CPin::SetIndex(kParam2Index)
00283         .SetName(kParam2Name)
00284         .SetUnit(kParam2Unit)
00285         .SetDescription(kParam2Description)
00286         .SetRangeMin(kParam2RangeMin)
00287         .SetRangeMax(kParam2RangeMax)
00288         .SetDefaultValue(kParam2DefaultValue)
00289         .SetQuantizedTo(kParam2QuantizedTo)
00290         .SetIsChangeableInRealTime(kParam2IsChangeableInRealTime)
00291     );
00292 
00293     SetPluginParameterPinInfo(CPin::SetIndex(kParam3Index)
00294         .SetName(kParam3Name)
00295         .SetUnit(kParam3Unit)
00296         .SetDescription(kParam3Description)
00297         .SetRangeMin(kParam3RangeMin)
00298         .SetRangeMax(kParam3RangeMax)
00299         .SetDefaultValue(kParam3DefaultValue)
00300         .SetQuantizedTo(kParam3QuantizedTo)
00301         .SetIsChangeableInRealTime(kParam3IsChangeableInRealTime)
00302     );
00303 
00304     // allocate ringbuffers and memory for results and temp memory for processing
00305     m_pfProcessBuffer   = zplfMalloc ((int)(m_afParameters[kBlockSize]));
00306     m_ptLocalTimeStamp  = new FEAPI_TimeStamp_t [iNumberOfAudioChannels];
00307     m_ppCRingBuffer     = new CRingBuffer<float>*[iNumberOfAudioChannels];
00308     m_ppResults         = new InternalResults_t*[iNumberOfAudioChannels];
00309     for (iCh = 0; iCh < iNumberOfAudioChannels; iCh++)
00310     {
00311         m_ppCRingBuffer[iCh]    = new CRingBuffer<float>((unsigned int)(m_afParameters[kBlockSize])<<1);
00312         m_ppResults[iCh]        = new InternalResults_t[m_iSizeOfResultBuffer];
00313         memset (m_ppResults[iCh], 0, sizeof (InternalResults_t) * m_iSizeOfResultBuffer);
00314     }
00315     memset (m_ptLocalTimeStamp, 0, sizeof(FEAPI_TimeStamp_t)*iNumberOfAudioChannels);
00316 
00317     return FEAPI_kNoError;
00318 }
00319 
00320 FEAPI_Error_t      CZeroCrossings::SetPluginParameter (int iParameterIndex, float fValue)
00321 {
00322     float   fMinValue,
00323             fMaxValue;
00324 
00325     if ((iParameterIndex >= this->GetPluginNumOfParameters ()) || (iParameterIndex < 0))
00326         return FEAPI_kUnspecifiedError;
00327 
00328     // check range
00329     switch (iParameterIndex)
00330     {
00331     case kBlockSize:
00332         fMinValue   = kParam1RangeMin;
00333         fMaxValue   = kParam1RangeMax;
00334         break;
00335     case kHopSize:
00336         fMinValue   = kParam2RangeMin;
00337         fMaxValue   = kParam2RangeMax;
00338         break;
00339     case kChannelMode:
00340         fMinValue   = kParam3RangeMin;
00341         fMaxValue   = kParam3RangeMax;
00342         break;
00343     default:
00344         return FEAPI_kUnspecifiedError;
00345     }
00346 
00347     if ((fValue < fMinValue) || (fValue > fMaxValue))
00348         return FEAPI_kUnspecifiedError;
00349 
00350     m_afParameters[iParameterIndex] = fValue;
00351 
00352     // since all parameters are non-realtime parameters, we can call initialize her for simplicity
00353     this->InitializePlugin (m_fSampleRate, this->GetPluginNumOfInputs (), 1, 0);
00354     
00355     return FEAPI_kUnknownError;
00356 }
00357 
00358 
00359 float       CZeroCrossings::GetPluginParameter (int iParameterIndex)
00360 {
00361     if ((iParameterIndex >= this->GetPluginNumOfParameters ()) || (iParameterIndex < 0))
00362         return FEAPI_kUnspecifiedError;
00363 
00364     return m_afParameters[iParameterIndex];
00365 }
00366 
00367 
00368 int         CZeroCrossings::GetPluginResultLatency (int iResultIndex)
00369 {
00370     return (int)m_afParameters[kBlockSize];
00371 }
00372 
00373 
00374 FEAPI_Error_t      CZeroCrossings::ProcessPluginDone ()
00375 {
00376     int iNumProcessChannels = this->GetPluginNumOfResults (), // either 1 or num of channels...
00377         iProcessBlockSize   = (int)(m_afParameters[kBlockSize]),
00378         iSamplesInBuffer    = m_ppCRingBuffer[0]->GetSamplesInBuffer ();
00379 
00380     for (int iCh = 0; iCh < iNumProcessChannels; iCh++)
00381     {
00382         int iTempResult = 0;
00383 
00384         m_ppCRingBuffer[iCh]->GetPostInc (m_pfProcessBuffer, iSamplesInBuffer);
00385         memset (&m_pfProcessBuffer[iSamplesInBuffer], 0, sizeof(float)*(iProcessBlockSize - iSamplesInBuffer));
00386 
00387         iTempResult = zplfZeroCrossings (m_pfProcessBuffer, iProcessBlockSize);
00388 
00389         m_ptLocalTimeStamp[iCh]  = m_ptLocalTimeStamp[iCh] + m_afParameters[kHopSize]*0.001F;
00390         this->WriteResult (iCh, iTempResult * 1.0F / iSamplesInBuffer, m_ptLocalTimeStamp[iCh]);
00391     }
00392 
00393     return FEAPI_kNoError;
00394 }
00395 
00396 FEAPI_Error_t      CZeroCrossings::ProcessPlugin (const float **ppfInputBuffer, const FEAPI_TimeStamp_t *ptTimeStamps, int iNumberOfFrames)
00397 {
00398     bool bDownmixToMono = (m_afParameters[kChannelMode] == 0)? true : false;
00399     int iCh,
00400         iIdx,
00401         iProcessBlockSize   = (int)(m_afParameters[kBlockSize]),
00402         iHopSize            = (int)(m_afParameters[kHopSize]*0.001F * m_fSampleRate + .5F),
00403         iNumFramesLeft      = iNumberOfFrames,
00404         iNumInputChannels   = this->GetPluginNumOfInputs (),
00405         iNumProcessChannels = this->GetPluginNumOfResults (), // either 1 or num of channels...,
00406         iSamplesInBuffer    = 0;
00407 
00408     if (!m_bIsInitialized)
00409         return FEAPI_kUnspecifiedError;
00410 
00411     // do time stamp handling, in both cases: no/defined time stamp
00412     if (ptTimeStamps)
00413     {
00414         for (iCh = 0; iCh < iNumInputChannels; iCh++)
00415             m_ptLocalTimeStamp[iCh] = ptTimeStamps[iCh] + iNumberOfFrames/m_fSampleRate;
00416     }
00417     else
00418     {
00419         for (iCh = 0; iCh < iNumInputChannels; iCh++)
00420             m_ptLocalTimeStamp[iCh]    += iNumberOfFrames/m_fSampleRate;
00421     }
00422 
00423     // if there are sufficient frames to process, do it!
00424     while (m_ppCRingBuffer[0]->GetSamplesInBuffer () + iNumFramesLeft >= iProcessBlockSize)
00425     {
00426         // check if we have to downmix to mono or not
00427         if (bDownmixToMono)
00428         {
00429             int iLength = (iHopSize < iNumFramesLeft) ? iHopSize : iNumFramesLeft;
00430             iNumProcessChannels = 1;
00431             // downmix and write to buffer, decr numframesleft
00432             memcpy (m_pfProcessBuffer, &ppfInputBuffer[0][iNumberOfFrames - iNumFramesLeft], sizeof(float) * iLength);
00433             for (iCh = 1; iCh < iNumInputChannels; iCh++)
00434             {
00435                 const float *pfBuffer = &ppfInputBuffer[iCh][iNumberOfFrames - iNumFramesLeft];
00436 
00437                 for (iIdx = 0; iIdx < iLength; iIdx++)
00438                     m_pfProcessBuffer[iIdx] += pfBuffer[iIdx];
00439             }
00440 
00441             // scale downmixed signal
00442             for (iIdx = 0; iIdx < iLength; iIdx++)
00443                 m_pfProcessBuffer[iIdx] *= 1.0F/iNumInputChannels;
00444 
00445             m_ppCRingBuffer[0]->PutPostInc (m_pfProcessBuffer, iLength);
00446         }
00447         else
00448         {
00449             for (iCh = 0; iCh < iNumInputChannels; iCh++)
00450                 m_ppCRingBuffer[iCh]->PutPostInc (&ppfInputBuffer[iCh][iNumberOfFrames - iNumFramesLeft], (iHopSize < iNumFramesLeft) ? iHopSize : iNumFramesLeft);
00451         }
00452 
00453         // decrement number of frames left in ppfInputBuffer
00454         iNumFramesLeft     -= (iHopSize < iNumFramesLeft) ? iHopSize : iNumFramesLeft;
00455 
00456         // get the current number of sample in ring buffer
00457         iSamplesInBuffer    = m_ppCRingBuffer[0]->GetSamplesInBuffer ();
00458 
00459         // if there are not enough sample in ring buffer, go on (note that this is not really possible...)
00460         if (iSamplesInBuffer < iProcessBlockSize)
00461             continue;
00462 
00463         // now do the processing
00464         for (iCh = 0; iCh < iNumProcessChannels; iCh++)
00465         {
00466             int iTempResult = 0;
00467     
00468             m_ptLocalTimeStamp[iCh]  = ptTimeStamps[iCh] + iNumberOfFrames/m_fSampleRate - (iSamplesInBuffer+iNumFramesLeft)/m_fSampleRate;
00469 
00470             // get data from ring bufffer and oncrement read pointer
00471             m_ppCRingBuffer[iCh]->GetOff (m_pfProcessBuffer, iProcessBlockSize, 0);
00472             m_ppCRingBuffer[iCh]->SetReadPos (m_ppCRingBuffer[iCh]->GetReadPos () + iHopSize);
00473 
00474             // calculation the number of zero crossings: pseudo: length(find((a(1:iBlockSize-1).*a(0:iBlockSize-2)) < 0))
00475             iTempResult = zplfZeroCrossings (m_pfProcessBuffer, iProcessBlockSize);
00476 
00477             // adjust time stamp and write result to output buffer
00478             this->WriteResult (iCh, iTempResult * 1.0F / iProcessBlockSize, m_ptLocalTimeStamp[iCh]);
00479         }
00480     }
00481 
00482     // if there are frames left in ppfInputBuffer, handle them here
00483     if (iNumFramesLeft > 0)
00484     {
00485         // write remaining frames to ringbuffer (distinguish downmix or not..., decr numframesleft)
00486         if (bDownmixToMono)
00487         {
00488             // downmix and write to buffer
00489             memcpy (m_pfProcessBuffer, &ppfInputBuffer[0][iNumberOfFrames - iNumFramesLeft], sizeof(float) * iNumFramesLeft);
00490             for (iCh = 1; iCh < iNumInputChannels; iCh++)
00491             {
00492                 const float *pfBuffer = &ppfInputBuffer[iCh][iNumberOfFrames - iNumFramesLeft];
00493 
00494                 for (iIdx = 0; iIdx < iNumFramesLeft; iIdx++)
00495                     m_pfProcessBuffer[iIdx] += pfBuffer[iIdx];
00496             }
00497             m_ppCRingBuffer[0]->PutPostInc (m_pfProcessBuffer, iNumFramesLeft);
00498         }
00499         else
00500         {
00501             for (iCh = 0; iCh < iNumInputChannels; iCh++)
00502                 m_ppCRingBuffer[iCh]->PutPostInc (&ppfInputBuffer[iCh][iNumberOfFrames - iNumFramesLeft], iNumFramesLeft);
00503         }
00504     }
00505 
00506     return FEAPI_kNoError;
00507 }
00508 
00509 int         CZeroCrossings::GetPluginSizeOfResult (int iResultIndex)
00510 {
00511     if ((iResultIndex >= this->GetPluginNumOfResults ()) || (iResultIndex < 0))
00512         return -1;
00513 
00514     if (m_ppResults[iResultIndex][0].bHoldsResult == true)
00515         return 1;
00516     else
00517         return 0;
00518 }
00519 
00520 
00521 FEAPI_Error_t      CZeroCrossings::GetPluginResult (int iResultIndex, float *pfResult, FEAPI_TimeStamp_t *ptTimeStamp)
00522 {
00523     if ((iResultIndex >= this->GetPluginNumOfResults ()) || (iResultIndex < 0))
00524         return FEAPI_kUnspecifiedError;
00525     
00526     if (m_ppResults[iResultIndex][0].bHoldsResult == false)
00527         return FEAPI_kUnspecifiedError;
00528 
00529     pfResult[0]     = m_ppResults[iResultIndex][0].fResult;
00530     ptTimeStamp[0]  = m_ppResults[iResultIndex][0].tTimeStamp;
00531 
00532     memmove (&m_ppResults[iResultIndex][0], &m_ppResults[iResultIndex][1], (m_iSizeOfResultBuffer - 1)*sizeof(InternalResults_t));
00533     m_ppResults[iResultIndex][m_iSizeOfResultBuffer-1].bHoldsResult = false;
00534 
00535     return FEAPI_kNoError;
00536 }
00537 
00538 
00539 FEAPI_Error_t      CZeroCrossings::ResetPlugin ()
00540 {
00541     for (int iCh = 0; iCh < this->GetPluginNumOfInputs (); iCh++)
00542     {
00543         m_ppCRingBuffer[iCh]->Reset ();
00544         m_ptLocalTimeStamp[iCh] = 0;
00545     }
00546     return FEAPI_kNoError;
00547 }
00548 
00549 
00550 float        CZeroCrossings::GetPluginProperty ( FEAPI_PluginProperty_t ePluginProperty)
00551 {
00552     switch (ePluginProperty)
00553     {
00554     case FEAPI_kMinSampleRate:
00555         {
00556             return 1;
00557         }
00558     case FEAPI_kMaxSampleRate:
00559         {
00560             return 1e38F;
00561         }
00562     case FEAPI_kMinChannels:
00563         {
00564             return 1;
00565         }
00566     case FEAPI_kMaxChannels:
00567         {
00568             return (float)((1<<30)-1);
00569         }
00570     case FEAPI_kMinFrameSize:
00571         {
00572             return 1;
00573         }
00574     case FEAPI_kMaxFrameSize:
00575         {
00576             return (float)((1<<30)-1);
00577         }
00578     case FEAPI_kOptFrameSize:
00579         {
00580             return floorf(m_afParameters[kHopSize] * 0.001F * m_fSampleRate + .5F);
00581         }
00582     default:
00583         {
00584             // this shall never happen ...
00585             return -1;
00586         }
00587     }
00588     return -1;
00589 }
00590 
00591 void CZeroCrossings::WriteResult (int iResultIdx, float fValue, FEAPI_TimeStamp_t tTimeStamp)
00592 {
00593     int     iCurrentIdx = 0;
00594 
00595     for (iCurrentIdx = 0; iCurrentIdx < m_iSizeOfResultBuffer; iCurrentIdx++)
00596     {
00597         ZASSERT (!m_ppResults[iCurrentIdx]);
00598         if (m_ppResults[iResultIdx][iCurrentIdx].bHoldsResult == false)
00599             break;
00600     }
00601     if (iCurrentIdx == m_iSizeOfResultBuffer)
00602     {
00603         // alloc new memory
00604         m_iSizeOfResultBuffer   <<= 1;
00605         for (int i = 0; i < this->GetPluginNumOfResults (); i++)
00606         {
00607             InternalResults_t *pTmp = new InternalResults_t[m_iSizeOfResultBuffer];
00608             memcpy (pTmp, m_ppResults[i], (m_iSizeOfResultBuffer>>1) * sizeof(InternalResults_t));
00609             memset (&pTmp[(m_iSizeOfResultBuffer>>1)], 0, (m_iSizeOfResultBuffer>>1) * sizeof(InternalResults_t));
00610             delete [] m_ppResults[i];
00611             m_ppResults[i]          = 0;
00612             m_ppResults[i]          = pTmp;
00613         }
00614     }
00615 
00616     m_ppResults[iResultIdx][iCurrentIdx].bHoldsResult  = true;
00617     m_ppResults[iResultIdx][iCurrentIdx].fResult       = fValue;
00618     m_ppResults[iResultIdx][iCurrentIdx].tTimeStamp    = tTimeStamp;
00619 
00620     return;
00621 }
00622 
00624 // entry points
00625 #ifdef __cplusplus                                                      
00626 extern "C" {                                                            
00627 #endif                                                              
00628 
00629 FEAPI_ENTRY_POINTS(CZeroCrossings)
00630 
00631 #ifdef __cplusplus                                                  
00632 }                                                               
00633 #endif
00634 

Generated on Fri Mar 23 10:28:54 2007 for FEAPI Plugin Documentation by  doxygen 1.3.9.1