Chaos Game Representation of audio signal
This is an implementation of the Chaos Game Representation of Audio Signals
Clone the repository and create the environment using the provided env.yml file. This will install cgr_audio in editable mode:
git clone https://github.com/jorgeavilacartes/cgr-audio.git
cd cgr-audio
conda env create -f env.yml
conda activate cgr-audio
pip install -e .You can also install directly from the repository using pip:
pip install git+https://github.com/jorgeavilacartes/cgr-audio.gitfrom the terminal run
streamlit run streamlit/app.pyAfter installation, the cgr-audio CLI is available. The main usage is:
cgr --help
Usage: cgr [OPTIONS] COMMAND [ARGS]...
cgr: Command-line interface for CGR from Audio files.
╭─ Options ───────────────────────────────────────────────────────────────────────────────╮
│ --install-completion Install completion for the current shell. │
│ --show-completion Show completion for the current shell, to copy it or │
│ customize the installation. │
│ --help Show this message and exit. │
╰─────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ──────────────────────────────────────────────────────────────────────────────╮
│ from-audio Create FCGR of an <audio>.wav (or portion of it) in .jpg format with │
│ black background. │
│ video Create a <video>.mp4 from a folder with FCGR as .jpg images, they are │
│ sorted by their name. │
│ from-sinusoidal Creates FCGR using a sinusoidal from given frequencies and their │
│ amplitudes │
│ as-numpy Create FCGR of an <audio>.wav (or portion of it) in .npy format, │
│ Intended to create datasets of FCGRs from audio files for training │
│ deep learning models. Optionally the FCGR can be saved as .jpg format │
│ with white background. │
│ add-audio Add audio to a video file. │
│ numpy-to-jpg Convert fcgr.npy to a fcgr.jpg image │
╰─────────────────────────────────────────────────────────────────────────────────────────╯cgr as-numpy -i example.wav -o output.npy --binarize --rescaleThis command processes example.wav and saves the Chaos Game Representation image as output.jpg.
By default it takes creates a (256x256) image from the first 5 seconds of the audio, with sampling rate 44100.
--binarizewill consider only presence absence to color each pixel (black and white). Otherwise a grayscale image will be created.--rescaleRescale the signal between [-1,1] before quantization, if the signal is not in that range, the mu-law quantization cannot be applied
import numpy as np
from pathlib import Path
# cgr-audio library
from cgr_audio.cgr import CGR
from cgr_audio.quantization import mu_law_quantization
from cgr_audio.utils import (
clip_signal,
rescale_signal,
)
mu = 255 # mu-law quantization. Number of bins in the discretization is (mu+1)
cgr = CGR(mu=mu)
sr = 44100 # sampling rate
tot_seconds = 10
def plot_cgr(signal):
signal = rescale_signal(signal) # to [0,1]
quantized_signal = mu_law_quantization(signal, mu=mu, center=True) # always center, CGR needs it
x,y = cgr(quantized_signal) # compute coordinates for each step
fig, ax = cgr.plot(x,y, figsize=(8,8), title=title, path_save=path_save)
return fig, ax
random_signal = np.random.randn(sr * tot_seconds)
plot_cgr(random_signal)Sinusoidal with a single frequency
t = np.linspace(0, tot_seconds, sr * tot_seconds, endpoint=False)
sinusoidal = 0.5 * np.sin(2 * np.pi * 349.23 * t)
plot_cgr(sinusoidal)t = np.linspace(0, tot_seconds, sr * tot_seconds, endpoint=False)
sinusoidal = 0.5 * np.sin(2 * np.pi * 440 * t) + 0.5 * np.sin(2 * np.pi * 349.23* t)
plot_cgr(sinusoidal)from cgr_audio import (
CGRrust,
FCGRrust,
mu_law_quantization_rust
)
fcgr_rust = FCGRrust(mu = 255, dim = 512, binarize = False)
t = np.linspace(0, tot_seconds, sr * tot_seconds, endpoint=False)
signal = 0.5 * np.sin(2 * np.pi * 440 * t) + 0.5 * np.sin(2 * np.pi * 349.23* t)
signal = rescale_signal(signal) # to [0,1]
quantized_signal = mu_law_quantization_rust(signal, mu=mu, center=True) # always center, CGR needs it
# here the rust extension returns a a list of lists (rows if the FCGR)
matrix = fcgr(sinusoidal)
fcgr = np.array(matrix)
# CGR rust works the same than CGR class,
cgr_rust = CGRrust(mu=255)
x,y = cgr_rust(quantized_signal) # compute coordinates for each step