Source code for taped.live_audio_pipelining
from functools import partial
import numpy as np
from IPython.core.display import clear_output
from taped.live_audio import launch_audio_tracking
from taped.util import find_a_default_input_device_index
from lined.tools import iterize
from lined import Pipeline
int16_max = np.iinfo(np.int16).max
[docs]def log_max_chk_to_fv(chk: np.ndarray, gain=50):
"""A chk_to_fv that has to do with volume"""
return [np.log(max(chk.max(), abs(chk.min()), 1)) / np.log(int16_max) * gain]
# return np.log(min(1, max(np.abs(chk)))) / np.log(int16_max) * gain
dflt_chk_to_fv = log_max_chk_to_fv
def ap_fv_to_viz(fv):
return f'/><{r"{" * int(sum(fv))}">'
dflt_fv_to_viz = ap_fv_to_viz
def ap_chk_to_viz(chk: np.ndarray, gain=50):
return ap_fv_to_viz(log_max_chk_to_fv(chk, gain))
dflt_chk_to_viz = ap_chk_to_viz
class DFLT:
gain = 10
cutoff = 50
dispstr = '*'
prefix = '|'
fv_num_sep = '\n'
def viz_norm(x, gain=10, cutoff=50):
return min(cutoff, x * gain)
def ascii_levels(x, viz_norm=viz_norm, dispstr=DFLT.dispstr, prefix=DFLT.prefix):
return prefix + dispstr * int(viz_norm(x))
dflt_num_to_viz_str = ascii_levels
def multipart_fv_str(fv,
num_to_viz_str=dflt_num_to_viz_str,
fv_num_sep=DFLT.fv_num_sep):
return fv_num_sep.join(map(num_to_viz_str, fv)) + '\n'
ascii_levels_fv_to_str = partial(multipart_fv_str,
num_to_viz_str=ascii_levels,
fv_num_sep=DFLT.fv_num_sep)
raw_fv_to_str = partial(multipart_fv_str,
num_to_viz_str=str,
fv_num_sep=DFLT.fv_num_sep)
dflt_fv_to_str = ascii_levels_fv_to_str
[docs]def chk_to_fv_viz(chk: np.ndarray,
chk_to_fv=dflt_chk_to_fv,
fv_to_str=dflt_fv_to_str):
"""Takes a chk and returns a string representing the fv. Meant to be displayed dynamically"""
fv = chk_to_fv(chk)
fv_str = fv_to_str(fv)
return fv_str
def refresh_and_print(iterator_output):
clear_output(wait=True)
n, viz = iterator_output
print(n, viz, sep='\n')
from collections import deque
[docs]class CallableDeque(deque):
def __call__(self, x):
self.append(x)
dflt_output_callback = refresh_and_print
[docs]def make_and_consume_iterator(iterator_func, *iterator_func_args, **iterator_func_kwargs):
"""make an consume and iterator"""
for _ in iterator_func(*iterator_func_args, **iterator_func_kwargs):
pass
def mk_launcher(chk_to_fv=dflt_chk_to_fv,
fv_to_viz=dflt_fv_to_viz,
input_device_index=None,
output_callback=dflt_output_callback):
if input_device_index is None:
input_device_index = find_a_default_input_device_index()
def chk_to_fv_viz(chk):
return fv_to_viz(chk_to_fv(chk))
pipe = Pipeline(launch_audio_tracking,
iterize(output_callback))
def launch():
make_and_consume_iterator(pipe,
chk_callback=chk_to_fv_viz,
input_device_index=input_device_index)
return launch