Class: DSP::Mfcc

Inherits:
Object
  • Object
show all
Defined in:
lib/dsprb/mfcc.rb,
sig/dsprb.rbs

Constant Summary collapse

DEFAULT_COEFFICIENTS =

Returns:

  • (::Integer)
13
DEFAULT_SIZE =

Returns:

  • (::Integer)
512
DEFAULT_WINDOW_SECONDS =

Returns:

  • (::Float)
0.025
DEFAULT_HOP_SECONDS =

Returns:

  • (::Float)
0.010

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(filterbank:, coefficients: DEFAULT_COEFFICIENTS, spectrum: nil) ⇒ Mfcc

Returns a new instance of Mfcc.

Parameters:

  • filterbank: (MelFilterbank)
  • coefficients: (::Integer) (defaults to: DEFAULT_COEFFICIENTS)
  • spectrum: (Spectrum, nil) (defaults to: nil)

Raises:

  • (ArgumentError)


19
20
21
22
23
24
25
26
27
# File 'lib/dsprb/mfcc.rb', line 19

def initialize(filterbank:, coefficients: DEFAULT_COEFFICIENTS, spectrum: nil)
  @filterbank = filterbank
  @coefficients = Integer(coefficients)
  @spectrum = spectrum || Spectrum.new(filterbank.size)

  raise ArgumentError, "coefficients must be positive, got #{@coefficients}" unless @coefficients.positive?

  freeze
end

Instance Attribute Details

#coefficients::Integer (readonly)

Returns the value of attribute coefficients.

Returns:

  • (::Integer)


10
11
12
# File 'lib/dsprb/mfcc.rb', line 10

def coefficients
  @coefficients
end

#filterbankMelFilterbank (readonly)

Returns the value of attribute filterbank.

Returns:



10
11
12
# File 'lib/dsprb/mfcc.rb', line 10

def filterbank
  @filterbank
end

#spectrumSpectrum (readonly)

Returns the value of attribute spectrum.

Returns:



10
11
12
# File 'lib/dsprb/mfcc.rb', line 10

def spectrum
  @spectrum
end

Class Method Details

.for(sample_rate:, size: DEFAULT_SIZE, coefficients: DEFAULT_COEFFICIENTS, **options) ⇒ Mfcc

Parameters:

  • sample_rate: (::Numeric)
  • size: (::Integer) (defaults to: DEFAULT_SIZE)
  • coefficients: (::Integer) (defaults to: DEFAULT_COEFFICIENTS)
  • (Object)

Returns:



12
13
14
15
16
17
# File 'lib/dsprb/mfcc.rb', line 12

def self.for(sample_rate:, size: DEFAULT_SIZE, coefficients: DEFAULT_COEFFICIENTS, **options)
  new(
    filterbank: MelFilterbank.new(sample_rate: sample_rate, size: size, **options),
    coefficients: coefficients
  )
end

Instance Method Details

#call(power) ⇒ ::Array[::Float]

Parameters:

Returns:

  • (::Array[::Float])


29
# File 'lib/dsprb/mfcc.rb', line 29

def call(power) = Dct.two(@filterbank.log_energies(power), @coefficients)

#sequence(waveform, window_seconds: DEFAULT_WINDOW_SECONDS, hop_seconds: DEFAULT_HOP_SECONDS, window: Window::DEFAULT, preemphasis: Framing::DEFAULT_PREEMPHASIS) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/dsprb/mfcc.rb', line 31

def sequence(
  waveform,
  window_seconds: DEFAULT_WINDOW_SECONDS,
  hop_seconds: DEFAULT_HOP_SECONDS,
  window: Window::DEFAULT,
  preemphasis: Framing::DEFAULT_PREEMPHASIS
)
  assert_rate!(waveform)

  length = waveform.seconds_to_samples(window_seconds)
  taper = Window.resolve(window).call(length)
  emphasized = preemphasis ? Framing.preemphasis(waveform.samples, coefficient: preemphasis) : waveform.samples

  Framing
    .frames(emphasized, window: length, hop: waveform.seconds_to_samples(hop_seconds))
    .map { |frame| call(@spectrum.power(Window.apply(frame, taper))) }
end