51 mKeyboard(mPiano.getKeyboard()),
52 mKeys(mKeyboard.getKeys()),
53 mNumberOfKeys(mKeyboard.getNumberOfKeys()),
54 mKeyNumberOfA4(mKeyboard.getKeyNumberOfA4()),
76 "Key vector length mismatch");
79 bool allkeysrecorded =
true;
80 bool somekeysrecorded =
false;
83 if (key.isRecorded()) somekeysrecorded =
true;
84 else allkeysrecorded =
false;
86 if (not somekeysrecorded)
88 MessageHandler::send<MessageCaluclationProgress>
91 LogW(
"Calculation started without data");
94 if (not allkeysrecorded)
96 MessageHandler::send<MessageCaluclationProgress>
99 LogW(
"Not all keys have been recorded");
105 bool consistent =
true;
108 Key &key = mKeys[keynumber];
112 LogW(
"Key %d: Frequency f=%f out of range.",keynumber,f);
118 LogW(
"Key %d: Inharmonicity B=%f out of range.",keynumber,B);
124 LogW(
"Key %d: Logspec size is %d, expected %d.",
126 static_cast<int>(spectrum.size()),
132 LogW(
"Key %d: Logspec norm = %f.",keynumber,
141 MessageHandler::send<MessageCaluclationProgress>
184 return f1 * n * sqrt((1+B*n*n)/(1+B));
207 else return 0.7071067811865475*sqrt((-1 + sqrt(1 + 4*B*(1+B)*x*x))/B);
233 int M = spectrum.size();
237 auto wave = [f,B,
this] (
int m)
239 auto envelope = [wave,f,
this] (
int m)
240 {
return pow(fabs(wave(m)),200.0/pow(
mtof(m)/f,1.5)); };
241 for (
int m=0; m<M; m++) spectrum[m] *= envelope(m);
259 int lowcutindex = std::min(static_cast<size_t>((5*
ftom(f)))/6,
NumberOfBins);
260 for (
int m=0; m<lowcutindex; m++) spectrum[m]=0;
286 double Ra = 12200.0*12200.0*f*f*f*f / (f*f+20.6*20.6) /
287 sqrt((f*f+107.7*107.7)*(f*f+737.9*737.9)) / (f*f+12200.0*12200.0);
288 mdBA[m] = 2.0+20*log10(Ra);
314 const double I0 = 1E-7;
317 double SPLA = 10 * log10(spectrum[m]/I0) +
mdBA[m];
318 if (SPLA<0) spectrum[m]=0;
319 else spectrum[m] = I0 * pow(10.0, SPLA/10.0);
343 double K=0, Y=0, KK=0, KY=0, N=0, BE=0;
348 double a = (N*KY-K*Y)/(N*KK-K*K);
349 double b = (KK*Y-K*KY)/(N*KK-K*K);
352 double B =
mKeys[k].getMeasuredInharmonicity();
353 bool B_is_valid = (B>0);
354 if (B>0 and BE>0 and N>5)
if (fabs(log(B/BE))>0.2) B_is_valid=
false;
358 K+=k; Y+=y; KK+=k*k; KY+=k*y; N++;
367 mKeys[k].setMeasuredInharmonicity(BE);
393 if (f<=0 or B<=0)
continue;
396 double factor = (1.0*(k-start))/(mNumberOfKeys-start);
397 double intensity = spectrum[m] * factor;
398 for (
int n=2; n<=6; ++n)
401 if (fn<20 or fn>10000)
continue;
403 for (
int i=mn-10; i<=mn+10; ++i)
405 spectrum[i] = intensity * pow(4,-n) * exp(-0.1*(i-mn)*(i-mn));
425 for (
int m=0; m<M; ++m)
428 const double df=55.0/f+f/2000.0;
431 for (
int ms = std::max(1,m-3*dm); ms<=std::min(m+3*dm,M-1); ms++)
433 double weight = exp(-1.0*(ms-m)*(ms-m)/dm/dm);
435 sum+=copy[ms]*weight;
437 if (norm>0) spectrum[m]=sum/norm;
double getRecordedFrequency() const
Get recorded frequency.
static double mtof(int m)
void extrapolateInharmonicity()
Extrapolate inharmonicity and estimate missing values.
std::vector< double > mdBA
const size_t NumberOfBins
Class describing a single piano key.
static const int NumberOfBins
Total number of slots: 9 octaves.
void initializeSPLAFilter()
Initialize the filter function in the vector mdBA.
void applyMollifier(Key &key)
double getEqualTempFrequency(int keynumber, double cents=0, double A4=0) const
Function returning the equal temperament.
double getInharmonicPartial(double n, double f1, double B)
Compute frequency of inharmonic partial.
AuditoryPreprocessing(Piano &piano)
Constructor.
double getMeasuredInharmonicity() const
Get estimated inharmonicity.
void convertToSPLA(SpectrumType &s)
Compute A-weighted sound pressure level SPLA.
Namespace for all entropy minimizer components.
bool checkDataConsistency()
Check consistency of the piano dataset.
std::vector< double > SpectrumType
Type of a log-binned spectrum.
static double ftom(double f)
const SpectrumType & getSpectrum() const
Get a read-only reference to mSpectrum.
double getInharmonicPartialIndex(double f, double f1, double B)
void improveHighFrequencyPeaks()
Improve high-frequency spectral lines.
void normalizeSpectrum(Key &key)
Normalize spectrum.
Key::SpectrumType SpectrumType
void cutLowFrequencies(Key &key)
Cut all frequencies below 5/6*f1 in order to reduce noise.
void cleanSpectrum(Key &key)
Clean logarithmically binned spectrum.
double getExpectedInharmonicity(double f) const
Compute expected approximative inharmonicity.