[api] add meltohz and hztomel, Slaney and Htk versions
authorPaul Brossier <piem@piem.org>
Sat, 17 Nov 2018 00:53:28 +0000 (01:53 +0100)
committerPaul Brossier <piem@piem.org>
Sat, 17 Nov 2018 00:53:28 +0000 (01:53 +0100)
src/musicutils.c [new file with mode: 0644]
src/musicutils.h

diff --git a/src/musicutils.c b/src/musicutils.c
new file mode 100644 (file)
index 0000000..14ef849
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+  Copyright (C) 2018 Paul Brossier <piem@aubio.org>
+
+  This file is part of aubio.
+
+  aubio is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  aubio is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with aubio.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "aubio_priv.h"
+#include "musicutils.h"
+
+smpl_t
+aubio_hztomel (smpl_t freq)
+{
+  const smpl_t lin_space = 3./200.;
+  const smpl_t split_hz = 1000.;
+  const smpl_t split_mel = split_hz * lin_space;
+  const smpl_t log_space = 27./LOG(6400/1000.);
+  if (freq < 0) {
+    AUBIO_WRN("hztomel: input frequency should be >= 0\n");
+    return 0;
+  }
+  if (freq < split_hz)
+  {
+    return freq * lin_space;
+  } else {
+    return split_mel + log_space * LOG (freq / split_hz);
+  }
+
+}
+
+smpl_t
+aubio_meltohz (smpl_t mel)
+{
+  const smpl_t lin_space = 200./3.;
+  const smpl_t split_hz = 1000.;
+  const smpl_t split_mel = split_hz / lin_space;
+  const smpl_t logSpacing = POW(6400/1000., 1/27.);
+  if (mel < 0) {
+    AUBIO_WRN("meltohz: input mel should be >= 0\n");
+    return 0;
+  }
+  if (mel < split_mel) {
+    return lin_space * mel;
+  } else {
+    return split_hz * POW(logSpacing, mel - split_mel);
+  }
+}
+
+smpl_t
+aubio_hztomel_htk (smpl_t freq)
+{
+  const smpl_t split_hz = 700.;
+  const smpl_t log_space = 1127.;
+  if (freq < 0) {
+    AUBIO_WRN("hztomel_htk: input frequency should be >= 0\n");
+    return 0;
+  }
+  return log_space * LOG (1 + freq / split_hz);
+}
+
+smpl_t
+aubio_meltohz_htk (smpl_t mel)
+{
+  const smpl_t split_hz = 700.;
+  const smpl_t log_space = 1./1127.;
+  if (mel < 0) {
+    AUBIO_WRN("meltohz_htk: input frequency should be >= 0\n");
+    return 0;
+  }
+  return split_hz * ( EXP ( mel * log_space) - 1.);
+}
+
index d9638ac..a659495 100644 (file)
@@ -86,6 +86,105 @@ smpl_t aubio_bintofreq (smpl_t bin, smpl_t samplerate, smpl_t fftsize);
 /** convert frequency (Hz) to frequency bin */
 smpl_t aubio_freqtobin (smpl_t freq, smpl_t samplerate, smpl_t fftsize);
 
+/** convert frequency (Hz) to mel
+
+  \param freq input frequency, in Hz
+
+  \return output mel
+
+  Converts a scalar from the frequency domain to the mel scale using Slaney
+  Auditory Toolbox's implementation:
+
+  If \f$ f < 1000 \f$, \f$ m = 3 f / 200 \f$.
+
+  If \f$ f >= 1000 \f$, \f$ m = 1000 + 27 \frac{{ln}(f) - ln(1000))}
+  {{ln}(6400) - ln(1000)}
+  \f$
+
+  See also
+  --------
+
+  aubio_meltohz(), aubio_hztomel_htk().
+
+*/
+smpl_t aubio_hztomel (smpl_t freq);
+
+/** convert mel to frequency (Hz)
+
+  \param mel input mel
+
+  \return output frequency, in Hz
+
+  Converts a scalar from the mel scale to the frequency domain using Slaney
+  Auditory Toolbox's implementation:
+
+  If \f$ f < 1000 \f$, \f$ f = 200 m/3 \f$.
+
+  If \f$ f \geq 1000 \f$, \f$ f = 1000 + \left(\frac{6400}{1000}\right)
+  ^{\frac{m - 1000}{27}} \f$
+
+  See also
+  --------
+
+  aubio_hztomel(), aubio_meltohz_htk().
+
+  References
+  ----------
+
+  Malcolm Slaney, *Auditory Toolbox Version 2, Technical Report #1998-010*
+  https://engineering.purdue.edu/~malcolm/interval/1998-010/
+
+*/
+smpl_t aubio_meltohz (smpl_t mel);
+
+/** convert frequency (Hz) to mel
+
+  \param freq input frequency, in Hz
+
+  \return output mel
+
+  Converts a scalar from the frequency domain to the mel scale, using the
+  equation defined by O'Shaughnessy, as implemented in the HTK speech
+  recognition toolkit:
+
+  \f$ m = 1127 + ln(1 + \frac{f}{700}) \f$
+
+  See also
+  --------
+
+  aubio_meltohz_htk(), aubio_hztomel().
+
+  References
+  ----------
+
+  Douglas O'Shaughnessy (1987). *Speech communication: human and machine*.
+  Addison-Wesley. p. 150. ISBN 978-0-201-16520-3.
+
+  HTK Speech Recognition Toolkit: http://htk.eng.cam.ac.uk/
+
+ */
+smpl_t aubio_hztomel_htk (smpl_t freq);
+
+/** convert mel to frequency (Hz)
+
+  \param mel input mel
+
+  \return output frequency, in Hz
+
+  Converts a scalar from the mel scale to the frequency domain, using the
+  equation defined by O'Shaughnessy, as implemented in the HTK speech
+  recognition toolkit:
+
+  \f$ f = 700 * {e}^\left(\frac{f}{1127} - 1\right) \f$
+
+  See also
+  --------
+
+  aubio_hztomel_htk(), aubio_meltohz().
+
+*/
+smpl_t aubio_meltohz_htk (smpl_t mel);
+
 /** convert frequency (Hz) to midi value (0-128) */
 smpl_t aubio_freqtomidi (smpl_t freq);