EMIPLIB

mipresample.h

Go to the documentation of this file.
00001 /*
00002     
00003   This file is a part of EMIPLIB, the EDM Media over IP Library.
00004   
00005   Copyright (C) 2006-2011  Hasselt University - Expertise Centre for
00006                       Digital Media (EDM) (http://www.edm.uhasselt.be)
00007 
00008   This library is free software; you can redistribute it and/or
00009   modify it under the terms of the GNU Lesser General Public
00010   License as published by the Free Software Foundation; either
00011   version 2.1 of the License, or (at your option) any later version.
00012 
00013   This library is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016   Lesser General Public License for more details.
00017 
00018   You should have received a copy of the GNU Lesser General Public
00019   License along with this library; if not, write to the Free Software
00020   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  
00021   USA
00022 
00023 */
00024 
00029 #ifndef MIPRESAMPLE_H
00030 
00031 #define MIPRESAMPLE_H
00032 
00033 #include "mipconfig.h"
00034 #include <stdio.h>
00035 
00036 #define MIPRESAMPLE_MAXCHANNELS                                                                 16
00037 
00042 template<class Tio, class Tcalc>
00043 bool MIPResample(const Tio *pInputFrames, int numInputFrames, int numInputChannels,
00044                  Tio *pOutputFrames, int numOutputFrames, int numOutputChannels)
00045 {
00046         if (numInputFrames < 1 || numOutputFrames < 1)
00047                 return false;
00048         if (numInputChannels < 1 || numOutputChannels < 1)
00049                 return false;
00050         if (numInputChannels > 1)
00051         {
00052                 if (numInputChannels != numOutputChannels && numOutputChannels != 1)
00053                         return false;
00054         }
00055         if (numOutputChannels > 1)
00056         {
00057                 if (numInputChannels != numOutputChannels && numInputChannels != 1)
00058                         return false;
00059         }
00060         
00061         if (numInputChannels > MIPRESAMPLE_MAXCHANNELS || numOutputChannels > MIPRESAMPLE_MAXCHANNELS)
00062                 return false;
00063 
00064         if (numInputFrames > numOutputFrames)
00065         {
00066                 const Tio *pIn = pInputFrames;
00067                 Tio *pOut = pOutputFrames;
00068 
00069                 for (int i = 0 ; i < numOutputFrames ; i++, pOut += numOutputChannels)
00070                 {
00071                         Tcalc inputSum[MIPRESAMPLE_MAXCHANNELS];
00072                                 
00073                         for (int j = 0 ; j < numInputChannels ; j++)
00074                                 inputSum[j] = 0;
00075 
00076                         int startFrame = (i*numInputFrames)/numOutputFrames;
00077                         int stopFrame = ((i+1)*numInputFrames)/numOutputFrames;
00078                         int num = stopFrame-startFrame;
00079                         
00080                         for (int j = 0 ; j < num ; j++, pIn += numInputChannels)
00081                         {
00082                                 for (int k = 0 ; k < numInputChannels ; k++)
00083                                         inputSum[k] += (Tcalc)pIn[k];
00084                         }
00085 
00086                         for (int j = 0 ; j < numInputChannels ; j++)
00087                                 inputSum[j] /= (Tcalc)num;
00088 
00089                         if (numInputChannels > 1 && numOutputChannels == 1)
00090                         {
00091                                 Tcalc sum = 0;
00092 
00093                                 for (int j = 0 ; j < numInputChannels ; j++)
00094                                         sum += inputSum[j];
00095                                 sum /= (Tcalc)numInputChannels;
00096                                 pOut[0] = (Tio)sum;
00097                         }
00098                         else if (numInputChannels == 1 && numOutputChannels > 1)
00099                         {
00100                                 Tio val = (Tio)inputSum[0];
00101                                 
00102                                 for (int j = 0 ; j < numOutputChannels ; j++)
00103                                         pOut[j] = val;
00104                         }
00105                         else // numInputChannels == numOutputChannels
00106                         {
00107                                 for (int j = 0 ; j < numOutputChannels ; j++)
00108                                         pOut[j] = (Tio)inputSum[j];
00109                         }
00110                 }
00111         }
00112         else if (numInputFrames < numOutputFrames)
00113         {
00114                 const Tio *pIn = pInputFrames;
00115                 Tio *pOut = pOutputFrames;
00116                 Tcalc stepValues[MIPRESAMPLE_MAXCHANNELS];
00117 
00118                 for (int j = 0 ; j < numInputChannels ; j++)
00119                         stepValues[j] = 0;
00120 
00121                 for (int i = 0 ; i < numInputFrames ; i++, pIn += numInputChannels)
00122                 {
00123                         int startFrame = (i*numOutputFrames)/numInputFrames;
00124                         int stopFrame = ((i+1)*numOutputFrames)/numInputFrames;
00125                         int num = stopFrame-startFrame;
00126                         Tcalc startValues[MIPRESAMPLE_MAXCHANNELS];
00127 
00128                         for (int j = 0 ; j < numInputChannels ; j++)
00129                                 startValues[j] = (Tcalc)pIn[j];
00130                         if (i < numInputFrames - 1)
00131                         {
00132                                 for (int j = 0 ; j < numInputChannels ; j++)
00133                                         stepValues[j] = (Tcalc)pIn[j+numInputChannels] - startValues[j];
00134                         }
00135 
00136                         for (int k = 0 ; k < num ; k++, pOut += numOutputChannels)
00137                         {
00138                                 Tcalc interpolation[MIPRESAMPLE_MAXCHANNELS];
00139 
00140                                 for (int j = 0 ; j < numInputChannels ; j++)
00141                                         interpolation[j] = startValues[j]+((Tcalc)j)*stepValues[j]/(Tcalc)num;
00142 
00143                                 if (numInputChannels > 1 && numOutputChannels == 1)
00144                                 {
00145                                         Tcalc sum = 0;
00146 
00147                                         for (int j = 0 ; j < numInputChannels ; j++)
00148                                                 sum += interpolation[j];
00149                                         sum /= (Tcalc)numInputChannels;
00150                                         pOut[0] = (Tio)sum;
00151                                 }
00152                                 else if (numInputChannels == 1 && numOutputChannels > 1)
00153                                 {
00154                                         Tio val = (Tio)interpolation[0];
00155                                         
00156                                         for (int j = 0 ; j < numOutputChannels ; j++)
00157                                                 pOut[j] = val;
00158                                 }
00159                                 else // numInputChannels == numOutputChannels
00160                                 {
00161                                         for (int j = 0 ; j < numOutputChannels ; j++)
00162                                                 pOut[j] = (Tio)interpolation[j];
00163                                 }
00164                         }
00165                 }
00166         }
00167         else // numInputFrames == numOutputFrames
00168         {
00169                 const Tio *pIn = pInputFrames;
00170                 Tio *pOut = pOutputFrames;
00171                 Tcalc inputSum[MIPRESAMPLE_MAXCHANNELS];
00172                 
00173                 for (int i = 0 ; i < numOutputFrames ; i++, pOut += numOutputChannels, pIn += numInputChannels)
00174                 {
00175                         for (int k = 0 ; k < numInputChannels ; k++)
00176                                 inputSum[k] = (Tcalc)pIn[k];
00177 
00178                         if (numInputChannels > 1 && numOutputChannels == 1)
00179                         {
00180                                 Tcalc sum = 0;
00181 
00182                                 for (int j = 0 ; j < numInputChannels ; j++)
00183                                         sum += inputSum[j];
00184                                 sum /= (Tcalc)numInputChannels;
00185                                 pOut[0] = (Tio)sum;
00186                         }
00187                         else if (numInputChannels == 1 && numOutputChannels > 1)
00188                         {
00189                                 Tio val = (Tio)inputSum[0];
00190                                 
00191                                 for (int j = 0 ; j < numOutputChannels ; j++)
00192                                         pOut[j] = val;
00193                         }
00194                         else // numInputChannels == numOutputChannels
00195                         {
00196                                 for (int j = 0 ; j < numOutputChannels ; j++)
00197                                         pOut[j] = (Tio)inputSum[j];
00198                         }
00199 
00200                 }
00201         }
00202 
00203         return true;
00204 }
00205 
00206 #endif // MIPRESAMPLE_H
00207