Source code for hum.gen.sine_mix
"""
Utils to mix sine waves
"""
from numpy import sin, arange, pi, ones, ndarray, random, all
from functools import partial
DFLT_N_SAMPLES = 21 * 2048
DFLT_SR = 44100
[docs]def mk_sine_wf(freq=5, n_samples=DFLT_N_SAMPLES, sr=DFLT_SR, phase=0, gain=1):
"""Make a sine waveform
:param freq: Frequency (in Hz)
:param n_samples: The number of samples of waveform you want
:param sr: Sample rate
:param phase: Phase (in radians)
:param gain: (A number to multiply the base sine wave by)
:return: Waveform. A numpy array of samples of the specified sine wave
>>> n_samples = random.randint(2,5)
>>> wf = mk_sine_wf(n_samples=n_samples)
>>> assert len(wf) == n_samples
>>> wf = mk_sine_wf(n_samples=3)
>>> assert all(wf == [0.0, 0.000712379226274755, 0.0014247580910282892])
"""
return gain * sin(phase + arange(n_samples) * 2 * pi * freq / sr)
[docs]def freq_based_stationary_wf(
freqs=(200, 400, 600, 800),
weights=None,
n_samples: int = DFLT_N_SAMPLES,
sr: int = DFLT_SR,
) -> ndarray:
"""
Makes a stationary waveform by mixing a number of freqs together, possibly with different weights.
:param freqs: List(-like) of frequencies (in Hz)
:param weights: The weights these frequencies should have (all weights will be normalized
:param n_samples: The number of samples of waveform you want
:param sr: Sample rate
:return: Waveform. A numpy array of samples of the specified sine wave
>>> n_samples = random.randint(2,5)
>>> wf = freq_based_stationary_wf(n_samples=n_samples)
>>> assert len(wf) == n_samples
>>> wf = freq_based_stationary_wf(n_samples = 3, weights = [1,2,3,4])
>>> assert all(wf == [0.0, 0.08534908048813569, 0.16988139234280178])
"""
if weights is None:
weights = ones(len(freqs))
assert len(freqs) == len(weights)
_mk_sine_wf = partial(mk_sine_wf, n_samples=n_samples, sr=sr)
wf = sum(_mk_sine_wf(freq) * weights[i] for i, freq in enumerate(freqs))
return wf / sum(weights)