CLAM-Development
1.1
|
00001 /* 00002 * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG) 00003 * UNIVERSITAT POMPEU FABRA 00004 * 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 * 00020 */ 00021 00022 #include "SpectrumConversions.hxx" 00023 #include "DataTypes.hxx" 00024 #include "CLAM_Math.hxx" 00025 00026 namespace CLAM 00027 { 00028 inline void AssertProperSize( TSize size, DataArray& buffer ) 00029 { 00030 if ( buffer.Size() != size ) 00031 { 00032 buffer.Resize( size ); 00033 buffer.SetSize( size ); 00034 } 00035 } 00036 00037 00038 void Polar2MagPhase ( const Array<Polar>& polarBuffer, DataArray& magBuffer, 00039 DataArray& phaseBuffer ) 00040 { 00041 TSize nBins = polarBuffer.Size(); 00042 00043 // target buffers resizing if necessary 00044 00045 AssertProperSize( nBins, magBuffer ); 00046 AssertProperSize( nBins, phaseBuffer ); 00047 00048 for ( TSize i = 0; i < nBins; i++ ) 00049 { 00050 magBuffer[i] = polarBuffer[i].Mag(); 00051 phaseBuffer[i] = polarBuffer[i].Ang(); 00052 } 00053 } 00054 00055 void Complex2MagPhase( const Array<Complex>& complBuffer, DataArray& magBuffer, DataArray& phaseBuffer ) 00056 { 00057 TSize nBins = complBuffer.Size(); 00058 00059 AssertProperSize( nBins, magBuffer ); 00060 AssertProperSize( nBins, phaseBuffer ); 00061 00062 for ( TSize i = 0; i < nBins; i++ ) 00063 { 00065 magBuffer[i] = complBuffer[i].Mag(); 00067 phaseBuffer[i] = complBuffer[i].Ang(); 00068 } 00069 } 00070 00071 void BPF2MagPhase( const BPF& magBpf, 00072 const BPF& phaseBpf, 00073 DataArray& magBuffer, 00074 DataArray& phaseBuffer, 00075 TSize nBins, 00076 TData specRange ) 00077 { 00078 AssertProperSize( nBins, magBuffer ); 00079 AssertProperSize( nBins, phaseBuffer ); 00080 00081 const TData delta = specRange/TData(nBins-1); 00082 TData freq = 0; 00083 00084 for ( TSize i = 0; i < nBins; i++ ) 00085 { 00086 magBuffer[i] = magBpf.GetValue( freq ); 00087 phaseBuffer[i] = phaseBpf.GetValue( freq ); 00088 00089 freq += delta; 00090 } 00091 } 00092 00093 void Log2LinearMagnitude( const DataArray& logBuffer, DataArray& linBuffer ) 00094 { 00095 const TSize nBins = logBuffer.Size(); 00096 static const TData inv_20 = 1.0f/20.0f; 00097 00098 AssertProperSize( nBins, linBuffer ); 00099 00100 for ( int i = 0; i < nBins; i++ ) 00101 { 00102 linBuffer[i] = CLAM_pow( TData(10), logBuffer[i]*inv_20 ) ; 00103 } 00104 } 00105 00106 void Log2LinearMagnitude( DataArray& dataBuffer ) 00107 { 00108 const TSize nBins = dataBuffer.Size(); 00109 static const TData inv_20 = 1.0f/20.0f; 00110 00111 for ( int i = 0; i < nBins; i++ ) 00112 { 00113 dataBuffer[i] = CLAM_pow( TData(10), dataBuffer[i]*inv_20 ) ; 00114 } 00115 } 00116 00117 void Complex2LogMagPhase(const Array<Complex> &src, DataArray &destMag, DataArray &destPhase) 00118 { 00119 CLAM_ASSERT(src.Size() == destMag.Size() && src.Size() == destPhase.Size(), "Complex2LogMagPhase() - input/output sizes inconsistent."); 00120 00121 const int n = src.Size(); 00122 for (int i = 0; i < n; ++i) 00123 { 00124 static const float minLinSquared = 1.0e-20f; 00125 static const float minLog = -200.f; // -200 dB 00126 00127 const float re = src[i].Real(); 00128 const float im = src[i].Imag(); 00129 00130 const float magSquared = re*re + im*im; 00131 00132 if (magSquared <= minLinSquared) 00133 { 00134 destMag[i] = minLog; 00135 } 00136 else 00137 { 00138 destMag[i] = 10.f*CLAM_log10(magSquared); // = 20*log10(CLAM_sqrt(re^2 + im^2)) 00139 } 00140 00141 destPhase[i] = src[i].Ang(); // = atan2(im. re) 00142 } 00143 } 00144 00145 void Linear2LogMagnitude( const DataArray& linearBuffer, DataArray& logData ) 00146 { 00147 const TSize nBins = linearBuffer.Size(); 00148 00149 AssertProperSize( nBins, logData ); 00150 00151 for ( int i = 0; i < nBins; i++ ) 00152 { 00153 logData[i]=CLAM_20log10(linearBuffer[i]); 00154 } 00155 00156 } 00157 00158 void Linear2LogMagnitude( DataArray& dataBuffer ) 00159 { 00160 const TSize nBins = dataBuffer.Size(); 00161 00162 for ( int i = 0; i < nBins; i++ ) 00163 { 00164 dataBuffer[i]=CLAM_20log10( dataBuffer[i] ); 00165 } 00166 } 00167 00168 } 00169