in StreamingASR/StreamingASR/app/src/main/cpp/librosa/librosa.h [101:143]
static Matrixf melfilter(int sr, int n_fft, int n_mels, int fmin, int fmax){
int n_f = n_fft/2+1;
Vectorf fft_freqs = (Vectorf::LinSpaced(n_f, 0.f, static_cast<float>(n_f-1))*sr)/n_fft;
float f_min = 0.f;
float f_sp = 200.f/3.f;
float min_log_hz = 1000.f;
float min_log_mel = (min_log_hz-f_min)/f_sp;
float logstep = logf(6.4f)/27.f;
auto hz_to_mel = [=](int hz, bool htk = false) -> float {
if (htk){
return 2595.0f*log10f(1.0f+hz/700.0f);
}
float mel = (hz-f_min)/f_sp;
if (hz >= min_log_hz){
mel = min_log_mel+logf(hz/min_log_hz)/logstep;
}
return mel;
};
auto mel_to_hz = [=](Vectorf &mels, bool htk = false) -> Vectorf {
if (htk){
return 700.0f*(Vectorf::Constant(n_mels+2, 10.f).array().pow(mels.array()/2595.0f)-1.0f);
}
return (mels.array()>min_log_mel).select(((mels.array()-min_log_mel)*logstep).exp()*min_log_hz, (mels*f_sp).array()+f_min);
};
float min_mel = hz_to_mel(fmin);
float max_mel = hz_to_mel(fmax);
Vectorf mels = Vectorf::LinSpaced(n_mels+2, min_mel, max_mel);
Vectorf mel_f = mel_to_hz(mels);
Vectorf fdiff = mel_f.segment(1, mel_f.size() - 1) - mel_f.segment(0, mel_f.size() - 1);
Matrixf ramps = mel_f.replicate(n_f, 1).transpose().array() - fft_freqs.replicate(n_mels + 2, 1).array();
Matrixf lower = -ramps.topRows(n_mels).array()/fdiff.segment(0, n_mels).transpose().replicate(1, n_f).array();
Matrixf upper = ramps.bottomRows(n_mels).array()/fdiff.segment(1, n_mels).transpose().replicate(1, n_f).array();
Matrixf weights = (lower.array()<upper.array()).select(lower, upper).cwiseMax(0);
auto enorm = (2.0/(mel_f.segment(2, n_mels)-mel_f.segment(0, n_mels)).array()).transpose().replicate(1, n_f);
weights = weights.array()*enorm;
return weights;
}