Module: Muze::Filters

Defined in:
lib/muze/filters/mel.rb,
lib/muze/filters/chroma_filter.rb

Overview

Filterbank generation utilities.

Constant Summary collapse

MEL_CACHE =
Muze::Core::BoundedCache.new(max_size: 64)
CHROMA_CACHE =
Muze::Core::BoundedCache.new(max_size: 64)

Class Method Summary collapse

Class Method Details

.chroma(sr:, n_fft:, n_chroma: 12, tuning: 0.0, ctroct: nil, octwidth: nil) ⇒ Numo::SFloat

Returns shape: [n_chroma, 1 + n_fft/2].

Parameters:

  • sr (Integer)
  • n_fft (Integer)
  • n_chroma (Integer) (defaults to: 12)
  • tuning (Float) (defaults to: 0.0)

Returns:

  • (Numo::SFloat)

    shape: [n_chroma, 1 + n_fft/2]



13
14
15
16
# File 'lib/muze/filters/chroma_filter.rb', line 13

def chroma(sr:, n_fft:, n_chroma: 12, tuning: 0.0, ctroct: nil, octwidth: nil)
  key = [sr, n_fft, n_chroma, tuning, ctroct, octwidth]
  CHROMA_CACHE.fetch(key) { build_chroma(sr:, n_fft:, n_chroma:, tuning:, ctroct:, octwidth:) }.dup
end

.hz_to_mel(hz, htk: false) ⇒ Float

Parameters:

  • hz (Float)
  • htk (Boolean) (defaults to: false)

Returns:

  • (Float)


104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/muze/filters/mel.rb', line 104

def hz_to_mel(hz, htk: false)
  return 2595.0 * Math.log10(1.0 + (hz / 700.0)) if htk

  f_sp = 200.0 / 3.0
  min_log_hz = 1000.0
  min_log_mel = min_log_hz / f_sp
  log_step = Math.log(6.4) / 27.0

  if hz < min_log_hz
    hz / f_sp
  else
    min_log_mel + (Math.log(hz / min_log_hz) / log_step)
  end
end

.mel(sr: 22_050, n_fft: 2048, n_mels: 128, fmin: 0.0, fmax: nil, htk: false, norm: nil) ⇒ Numo::SFloat

Returns shape: [n_mels, 1 + n_fft/2].

Parameters:

  • sr (Integer) (defaults to: 22_050)
  • n_fft (Integer) (defaults to: 2048)
  • n_mels (Integer) (defaults to: 128)
  • fmin (Float) (defaults to: 0.0)
  • fmax (Float, nil) (defaults to: nil)
  • htk (Boolean) (defaults to: false)
  • norm (Symbol, nil) (defaults to: nil)

Returns:

  • (Numo::SFloat)

    shape: [n_mels, 1 + n_fft/2]



17
18
19
20
# File 'lib/muze/filters/mel.rb', line 17

def mel(sr: 22_050, n_fft: 2048, n_mels: 128, fmin: 0.0, fmax: nil, htk: false, norm: nil)
  key = [sr, n_fft, n_mels, fmin, fmax, htk, norm]
  MEL_CACHE.fetch(key) { build_mel(sr:, n_fft:, n_mels:, fmin:, fmax:, htk:, norm:) }.dup
end

.mel_frequencies(n_mels:, fmin:, fmax:, htk: false) ⇒ Numo::SFloat

Parameters:

  • n_mels (Integer)
  • fmin (Float)
  • fmax (Float)
  • htk (Boolean) (defaults to: false)

Returns:

  • (Numo::SFloat)

Raises:



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/muze/filters/mel.rb', line 27

def mel_frequencies(n_mels:, fmin:, fmax:, htk: false)
  validate_frequency_bounds!(sr: fmax * 2.0, fmin:, fmax:)
  raise Muze::ParameterError, "n_mels must be positive" unless n_mels.positive?

  mel_min = hz_to_mel(fmin, htk:)
  mel_max = hz_to_mel(fmax, htk:)
  Numo::SFloat.cast(
    Array.new(n_mels) do |idx|
      mel_to_hz(mel_min + ((mel_max - mel_min) * idx / [n_mels - 1, 1].max.to_f), htk:)
    end
  )
end

.mel_to_hz(mel_value, htk: false) ⇒ Float

Parameters:

  • mel_value (Float)
  • htk (Boolean) (defaults to: false)

Returns:

  • (Float)


122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/muze/filters/mel.rb', line 122

def mel_to_hz(mel_value, htk: false)
  return 700.0 * ((10.0**(mel_value / 2595.0)) - 1.0) if htk

  f_sp = 200.0 / 3.0
  min_log_hz = 1000.0
  min_log_mel = min_log_hz / f_sp
  log_step = Math.log(6.4) / 27.0

  if mel_value < min_log_mel
    mel_value * f_sp
  else
    min_log_hz * Math.exp(log_step * (mel_value - min_log_mel))
  end
end