32 const TData AudioDescriptors::mEpsilon = 1e-5;
46 SetTemporalCentroid(initVal);
49 SetZeroCrossingRate(initVal);
51 SetLogAttackTime(initVal);
55 void AudioDescriptors::DefaultInit() {
60 void AudioDescriptors::CopyInit(
const AudioDescriptors & copied) {
61 mpAudio=copied.mpAudio;
74 mIsAttackTimeComputed=
false;
81 if (HasTemporalCentroid())
87 if(HasZeroCrossingRate())
88 SetZeroCrossingRate(ComputeZeroCrossingRate());
90 SetRiseTime(ComputeAttackTime());
91 if(HasLogAttackTime())
92 SetLogAttackTime(ComputeLogAttackTime());
94 SetDecrease(ComputeDecrease());
97 TData AudioDescriptors::ComputeZeroCrossingRate()
101 int signChangeCount = 0;
103 bool wasPositive = data[0] > 0.0;
105 for (
int i=1; i<size; i++)
107 const bool isPositive = (data[i] > 0.0);
108 if (wasPositive == isPositive)
continue;
111 wasPositive = isPositive;
114 return ((
TData)signChangeCount)/size;
117 TData AudioDescriptors::ComputeAttackTime()
119 if(mIsAttackTimeComputed)
return mComputedAttackTime;
121 const DataArray& data = mpAudio->GetBuffer();
125 energyEnv.
Resize(dataSize);
126 energyEnv.SetSize(dataSize);
129 const TData omega_c = 2*
PI*20/mpAudio->GetSampleRate();
130 const TData alpha = (1-sin(omega_c)) / cos(omega_c);
132 const TData b0 = (1-alpha)/2;
133 const TData a1 = -alpha;
137 TData maxVal = energyEnv[0];
141 if (energyEnv[i] > maxVal) maxVal = energyEnv[i];
145 const TData startThreshold = 0.02*maxVal;
146 const TData stopThreshold = 0.80*maxVal;
149 for (startIdx=0; startIdx<
dataSize; startIdx++) {
150 if (energyEnv[startIdx] > startThreshold)
break;
154 for (stopIdx=startIdx; stopIdx<
dataSize; stopIdx++) {
155 if (energyEnv[stopIdx] > stopThreshold)
break;
158 mComputedAttackTime=(stopIdx - startIdx) / mpAudio->GetSampleRate();
159 mIsAttackTimeComputed=
true;
160 return mComputedAttackTime;
164 TData AudioDescriptors::ComputeLogAttackTime()
167 if (mComputedAttackTime==0)
168 return log10(mEpsilon);
169 return log10(mComputedAttackTime);
173 TData AudioDescriptors::ComputeDecrease()
175 const DataArray& data = mpAudio->GetBuffer();
179 const double omega_c = 2*
PI*20/mpAudio->GetSampleRate();
180 const double alpha = (1-sin(omega_c)) / cos(omega_c);
182 const double b0 = (1-alpha)/2;
183 const double a1 = -alpha;
187 TData correctedY = y<mEpsilon ? mEpsilon : y;
188 double logEnv = log10(correctedY);
190 TData maxVal = logEnv;
199 correctedY = y<mEpsilon ? mEpsilon : y;
200 const double logEnv = log10(correctedY);
216 const long N = dataSize - maxIdx;
217 TData sumX = N*(N + 2*maxIdx - 1)/2;
219 TData num = N * sumXY - sumX * sumY;
220 TData den = N * sumXX - sumX * sumX;
222 return (num / den) * mpAudio->GetSampleRate();
233 tmpD.SetMean(a.GetMean()*mult);
235 if (a.HasTemporalCentroid())
237 tmpD.SetTemporalCentroid(a.GetTemporalCentroid()*mult);
241 tmpD.SetEnergy(a.GetEnergy()*mult);
245 tmpD.SetVariance(a.GetVariance()*mult);
247 if(a.HasZeroCrossingRate())
249 tmpD.SetZeroCrossingRate(a.GetZeroCrossingRate()*mult);
253 tmpD.SetRiseTime(a.GetRiseTime()*mult);
255 if(a.HasLogAttackTime())
257 tmpD.SetLogAttackTime(a.GetLogAttackTime()*mult);
261 tmpD.SetDecrease(a.GetDecrease()*mult);
275 if (a.HasMean() && b.HasMean() )
279 tmpD.SetMean(a.GetMean()*b.GetMean() );
281 if (a.HasTemporalCentroid() && b.HasTemporalCentroid() )
283 tmpD.AddTemporalCentroid();
285 tmpD.SetTemporalCentroid(a.GetTemporalCentroid()*b.GetTemporalCentroid() );
287 if (a.HasEnergy() && b.HasEnergy() )
291 tmpD.SetEnergy(a.GetEnergy()*b.GetEnergy() );
293 if(a.HasVariance() && b.HasVariance() )
297 tmpD.SetVariance(a.GetVariance()*b.GetVariance() );
299 if(a.HasZeroCrossingRate() && b.HasZeroCrossingRate() )
301 tmpD.AddZeroCrossingRate();
303 tmpD.SetZeroCrossingRate(a.GetZeroCrossingRate()*b.GetZeroCrossingRate() );
305 if(a.HasRiseTime() && b.HasRiseTime() )
309 tmpD.SetRiseTime(a.GetRiseTime()*b.GetRiseTime() );
311 if(a.HasLogAttackTime() && b.HasLogAttackTime() )
313 tmpD.AddLogAttackTime();
315 tmpD.SetLogAttackTime(a.GetLogAttackTime()*b.GetLogAttackTime() );
317 if(a.HasDecrease() && b.HasDecrease() )
321 tmpD.SetDecrease(a.GetDecrease()*b.GetDecrease() );
330 if (a.HasMean() && b.HasMean() )
334 tmpD.SetMean(a.GetMean()+b.GetMean() );
336 if (a.HasTemporalCentroid() && b.HasTemporalCentroid() )
338 tmpD.AddTemporalCentroid();
340 tmpD.SetTemporalCentroid(a.GetTemporalCentroid()+b.GetTemporalCentroid() );
342 if (a.HasEnergy() && b.HasEnergy() )
346 tmpD.SetEnergy(a.GetEnergy()+b.GetEnergy() );
348 if(a.HasVariance() && b.HasVariance() )
352 tmpD.SetVariance(a.GetVariance()+b.GetVariance() );
354 if(a.HasZeroCrossingRate() && b.HasZeroCrossingRate() )
356 tmpD.AddZeroCrossingRate();
358 tmpD.SetZeroCrossingRate(a.GetZeroCrossingRate()+b.GetZeroCrossingRate() );
360 if(a.HasRiseTime() && b.HasRiseTime() )
364 tmpD.SetRiseTime(a.GetRiseTime()+b.GetRiseTime() );
366 if(a.HasLogAttackTime() && b.HasLogAttackTime() )
368 tmpD.AddLogAttackTime();
370 tmpD.SetLogAttackTime(a.GetLogAttackTime()+b.GetLogAttackTime() );
372 if(a.HasDecrease() && b.HasDecrease() )
376 tmpD.SetDecrease(a.GetDecrease()+b.GetDecrease() );