Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
self.filterbank.set_mel_coeffs_htk(
self._config['mic_rate'],
self._config['min_frequency'],
self._config['max_frequency'])
# Frequencies wil be linearly spaced in the mel scale
melbank_mel = np.linspace(
aubio.hztomel(self._config['min_frequency']),
aubio.hztomel(self._config['max_frequency']),
self._config['samples'])
self.melbank_frequencies = np.array(
[aubio.meltohz(mel) for mel in melbank_mel])
# Coefficients based on Scott's audio reactive led project
if self._config['coeffs_type'] == 'scott':
(melmat, center_frequencies_hz, freqs) = mel.compute_melmat(
num_mel_bands=self._config['samples'],
freq_min=self._config['min_frequency'],
freq_max=self._config['max_frequency'],
num_fft_bands=int(self._config['fft_size'] // 2) + 1,
sample_rate=self._config['mic_rate'])
self.filterbank = aubio.filterbank(
self._config['samples'],
self._config['fft_size'])
self.filterbank.set_coeffs(melmat.astype(np.float32))
self.melbank_frequencies = center_frequencies_hz
# "Mel"-spacing based on Scott's audio reactive led project. This
# should in theory be the same as the above, but there seems to be
# slight differences. Leaving both for science!
if self._config['coeffs_type'] == 'scott_mel':
def hertz_to_scott(freq):
def compute_melmat(self):
return mel.compute_melmat(
num_mel_bands=self._config['samples'],
freq_min=self._config['min_frequency'],
freq_max=self._config['max_frequency'],
num_fft_bands=int(self._config['nfft'] // 2) + 1,
sample_rate=self._config['mic_rate'])
from ledfx.effects.audio import AudioReactiveEffect, MIN_MIDI, MAX_MIDI
from ledfx.effects.gradient import GradientEffect
from ledfx.effects import mix_colors
from ledfx.color import COLORS
import voluptuous as vol
import numpy as np
import aubio
class PitchSpectrumAudioEffect(AudioReactiveEffect, GradientEffect):
NAME = "PitchSpectrum"
CONFIG_SCHEMA = vol.Schema({
vol.Optional('blur', description='Amount to blur the effect', default = 1.0): vol.Coerce(float),
vol.Optional('mirror', description='Mirror the effect', default = True): bool,
vol.Optional('fade_rate', description='Rate at which notes fade', default = 0.15): vol.All(vol.Coerce(float), vol.Range(min=0.0, max=1.0)),
vol.Optional('responsiveness', description='Responsiveness of the note changes', default = 0.15): vol.All(vol.Coerce(float), vol.Range(min=0.0, max=1.0)),
})
def config_updated(self, config):
win_s = 1024
hop_s = 48000 // 60
tolerance = 0.8
# TODO: Move into the base audio effect class
filter_banks = np.sum(filter_banks, axis=0)
filter_banks = filter_banks**2.0
# Gain normalization
self.mel_gain.update(np.max(filter_banks))
filter_banks /= self.mel_gain.value
filter_banks = self.mel_smoothing.update(filter_banks)
# # TODO: Look into some better gain normalization as there seems to be some
# # issues with variable volume.
# self.mel_gain.update(np.mean(gaussian_filter1d(filter_banks, sigma=1.0)))
# #filter_banks -= (np.mean(filter_banks, axis=0) + 1e-8)
# filter_banks /= self.mel_gain.value
# filter_banks = self.mel_smoothing.update(filter_banks)
self._ledfx.events.fire_event(GraphUpdateEvent(
'legacyMelbank', filter_banks, self.melbank_frequencies))
return filter_banks
"""Returns the raw melbank curve"""
if self.volume() > self._config['min_volume']:
# Compute the filterbank from the frequency information
raw_filter_banks = self.filterbank(self.frequency_domain())
raw_filter_banks = raw_filter_banks ** 2.0
self.mel_gain.update(np.max(smooth(raw_filter_banks, sigma=1.0)))
filter_banks = raw_filter_banks / self.mel_gain.value
filter_banks = self.mel_smoothing.update(filter_banks)
else:
raw_filter_banks = np.zeros(self._config['samples'])
filter_banks = raw_filter_banks
if self._ledfx.dev_enabled():
self._ledfx.events.fire_event(GraphUpdateEvent(
'raw', raw_filter_banks, np.array(self.melbank_frequencies)))
self._ledfx.events.fire_event(GraphUpdateEvent(
'melbank', filter_banks, np.array(self.melbank_frequencies)))
return filter_banks
if self.volume() > self._config['min_volume']:
# Compute the filterbank from the frequency information
raw_filter_banks = self.filterbank(self.frequency_domain())
raw_filter_banks = raw_filter_banks ** 2.0
self.mel_gain.update(np.max(smooth(raw_filter_banks, sigma=1.0)))
filter_banks = raw_filter_banks / self.mel_gain.value
filter_banks = self.mel_smoothing.update(filter_banks)
else:
raw_filter_banks = np.zeros(self._config['samples'])
filter_banks = raw_filter_banks
if self._ledfx.dev_enabled():
self._ledfx.events.fire_event(GraphUpdateEvent(
'raw', raw_filter_banks, np.array(self.melbank_frequencies)))
self._ledfx.events.fire_event(GraphUpdateEvent(
'melbank', filter_banks, np.array(self.melbank_frequencies)))
return filter_banks
# force all zeros when below the volume threshold
if self._volume_filter.value > self._config['min_volume']:
self._processed_audio_sample = self._raw_audio_sample
# Perform a pre-emphasis to balance the highs and lows
if self.pre_emphasis:
self._processed_audio_sample = self.pre_emphasis(self._raw_audio_sample)
# Pass into the phase vocoder to get a windowed FFT
self._frequency_domain = self._phase_vocoder(self._processed_audio_sample)
else:
self._frequency_domain = self._frequency_domain_null
# Light up some notifications for developer mode
if self._ledfx.dev_enabled():
self._ledfx.events.fire_event(GraphUpdateEvent(
'fft', self._frequency_domain.norm, self._frequency_domain_x))
coeffs = self.filterbank.get_coeffs()
coeffs /= np.max(coeffs, axis=-1)[:, None]
self.filterbank.set_coeffs(coeffs)
# Find the indexes for each of the frequency ranges
for i in range(0, len(self.melbank_frequencies) - 1):
if self.melbank_frequencies[i] < FREQUENCY_RANGES_SIMPLE['low'].max:
self.lows_index = i
elif self.melbank_frequencies[i] < FREQUENCY_RANGES_SIMPLE['mid'].max:
self.mids_index = i
elif self.melbank_frequencies[i] < FREQUENCY_RANGES_SIMPLE['high'].max:
self.highs_index = i
# Build up some of the common filters
self.mel_gain = ExpFilter(np.tile(1e-1, self._config['samples']), alpha_decay=0.01, alpha_rise=0.99)
self.mel_smoothing = ExpFilter(np.tile(1e-1, self._config['samples']), alpha_decay=0.2, alpha_rise=0.99)
self.common_filter = ExpFilter(alpha_decay = 0.99, alpha_rise = 0.01)
coeffs /= np.max(coeffs, axis=-1)[:, None]
self.filterbank.set_coeffs(coeffs)
# Find the indexes for each of the frequency ranges
for i in range(0, len(self.melbank_frequencies) - 1):
if self.melbank_frequencies[i] < FREQUENCY_RANGES_SIMPLE['low'].max:
self.lows_index = i
elif self.melbank_frequencies[i] < FREQUENCY_RANGES_SIMPLE['mid'].max:
self.mids_index = i
elif self.melbank_frequencies[i] < FREQUENCY_RANGES_SIMPLE['high'].max:
self.highs_index = i
# Build up some of the common filters
self.mel_gain = ExpFilter(np.tile(1e-1, self._config['samples']), alpha_decay=0.01, alpha_rise=0.99)
self.mel_smoothing = ExpFilter(np.tile(1e-1, self._config['samples']), alpha_decay=0.2, alpha_rise=0.99)
self.common_filter = ExpFilter(alpha_decay = 0.99, alpha_rise = 0.01)
if self._config['coeffs_type'] != 'scott' and self._config['coeffs_type'] == 'scott_mel':
coeffs = self.filterbank.get_coeffs()
coeffs /= np.max(coeffs, axis=-1)[:, None]
self.filterbank.set_coeffs(coeffs)
# Find the indexes for each of the frequency ranges
for i in range(0, len(self.melbank_frequencies) - 1):
if self.melbank_frequencies[i] < FREQUENCY_RANGES_SIMPLE['low'].max:
self.lows_index = i
elif self.melbank_frequencies[i] < FREQUENCY_RANGES_SIMPLE['mid'].max:
self.mids_index = i
elif self.melbank_frequencies[i] < FREQUENCY_RANGES_SIMPLE['high'].max:
self.highs_index = i
# Build up some of the common filters
self.mel_gain = ExpFilter(np.tile(1e-1, self._config['samples']), alpha_decay=0.01, alpha_rise=0.99)
self.mel_smoothing = ExpFilter(np.tile(1e-1, self._config['samples']), alpha_decay=0.2, alpha_rise=0.99)
self.common_filter = ExpFilter(alpha_decay = 0.99, alpha_rise = 0.01)