Detailed Documentation
STRAUSS (Sonification Tools and Resources for Analysis Using Sound Synthesis)
This module provides a toolkit for sonification, i.e. the representation of data using sound.
User-Facing Modules
These are the user-facing modules of the strauss code, that are used to define a Sonification.
Sources
The
sourcessubmodule: representing data as sound sources.This submodule deals with the mapping of input datasets to the parameters controlling sound in the eventual sonification.
- strauss.sources.mappable
List of strings indicating possible sonification parameters to which data can be mapped.
- Type:
list(str)
- strauss.sources.evolvable
List of strings indicating the subset of mappable parameters that can be evolved continuosly for an individual Source.
- Type:
list(str)
- strauss.sources.param_limits
List of tuples indicating the default numerical ranges bounding corresponding mappable parameter (e.g. 0-1 for volume).
- Type:
list(tuple)
- strauss.sources.param_lim_dict
Dictionary combining mappable (keys) and param_limits (items).
- Type:
dictTodo
Store mappable, evolvable and parameter ranges in YAML files (cleaner).
Specialised Event and Object child classes (eg. spectralisation).
- class strauss.sources.Events(mapped_quantities)[source]
Bases:
SourceRepresent data as time-discrete events.
Child class of Source, for Event-type sources. Each Event is discrete in time with single data values mapped to each sonification parameter.
- fromdict(datadict)[source]
Take input data from dictionary
- Parameters:
datadict (
dict) – keys are self.mapped_values, with entries corresponding to the input data. Multiple sources are provided aslists, with data for each source corresponding to the values. Single sources can be represented as single values.
- class strauss.sources.Objects(mapped_quantities)[source]
Bases:
SourceRepresent data as time-continuous objects.
Child class of Source. In addition to supporting single values for each parameter (see Events class), objects also support time evolution for evolvable parameters, given a time-evo mapping.
Todo
implement
fromfilemethod
- fromdict(datadict)[source]
Take input data from dictionary
- Parameters:
datadict (
dict) – keys are self.mapped_values, with entries corresponding to the input data. Multiple sources are provided as eitherlistsor 2Dnumpy.arrayobjects, with each source corresponding to the entries or columns respectively. Single sources can be represented as single values or 1Dnumpy.array(for evolving parameters).
- class strauss.sources.Source(mapped_quantities)[source]
Bases:
objectGeneric source class defining common methods/attributes
Source and its child classes represent the input data, and its mapping to sonification parameters.
Note
Source isn’t used directly, instead use child classes Events or Objects.
- mapped_quantities
The subset of parameters to which data will be mapped.
- Type:
list(str)
- raw_mapping
Housing the input mapped parameters and data, with keys corresponding to
mapped_quantities.
- Type:
dict
- mapping
processed mapping
dictrescaled to parameter ranges, or interpolation funtions for evolving parameters.
- Type:
dict
- Raises:
UnrecognisedProperty – if mapped_quantities entry not in mappable.
- apply_mapping_functions(map_funcs={}, map_lims={}, param_lims={})[source]
Taking input data and mapping to parameters.
This function does the bulk of the work for Source classes, taking each input data variable and applying the mapping function (x’ = x by default), descaling by the x’ upper and lower limits and rescaling to the sonification parameter limits. These values are stored for non-evolving parameters, while for evolving properties they are converted to interpolation functions.
- Parameters:
map_funcs (
dict, optional) – dict with keys that must be a subset self.mapped_quantities. Entries are then function-like objects for converting input data (e.g. taking log of a data set). If not provided, each conversion function is assumed to be f(x) = x.map_lims (
dict, optional) – dict with keys that must be a subset self.mapped_quantities. Entries are tuples indicating the lower (index 0) and upper (index 1) limits on the converted input data values. numerical values indicate absolute limits, while strings are used to indicate percentiles [e.g. (‘10%’,’95%’)]. converted data values are clipped to these limits. If not provided, (0,1) is assumed.param_lims (
dict, optional) – dict with keys that must be a subset self.mapped_quantities. Entries are tuples indicating the lower (index 0) and upper (index 1) limits of the mapped sonification parameters. The map_lims ranges are resaled to these ranges to give the parameter values. If not provided, the default param_lim_dict values are taken.Note
There is special behaviour for the polar and azimuth parameters, to ensure shortest angular distance when interpolating across the 0-2pi and 0-pi boundaries.
Score
The
scoresubmodule: musical constraints on whatSourcescan playThis submodule is intended to control any musical aspects of the sonification, by providing constraints on harmonic and rhythmic aspects.
Todo
Incorporate more rhythmic options, such as quantisation
Have the
Scoreclass handle pitch and rhythm assignment fromSourcesdirectly, instead of theSonificationclass.Support chord change intervals as a mapped parameter
Provide template chord charts for users
- class strauss.score.Score(chord_sequence, length, pitch_binning='adaptive')[source]
Bases:
objectClass defining the musical score for the sonification
The Score class controls the musical aspects of the sonification. Currently supports a chordal score, defining a set of notes that can be played for each section of the simulation. The score also controls the length of the sonification.
Note
Currently, no rhythmic constraints are incorporated in the score. Chords are divided evenly over the length of the sonification. For example for a one minute sonification (
length = '1m 0s') thechord_sequence = "Am7_3 | D9_3 | Gmaj7_2"plays each chord for 20s each. Chaining the same chord can be used to change the length of these intervals, (e.g.chord_sequence = "F_3 | F_3 | C_4"plays F for 40s and C for 20s, [[“C2”,”G3”,”E4”]*37+[“G2”,”D3”,”B4”]*23] would play the C voicing for 37s and G voicing for 23s).
- strauss.score.parse_chord_sequence(chord_sequence)[source]
parse a chord sequence from a string
- Parameters:
chord_sequence (
str) – chord sequence to parse, with chord names appended with ‘_N’ where N is the root octave of the chord, and each chord is separated by a pipe character, ‘|’.- Returns:
the chord sequence represented as a list of lists, where each sub-list is a chord comprised of strings representing each note in scientific pitch notation (e.g. ‘A4’)
- Return type:
note_list (
list(list))
Generator
The
generatorsubmodule: creating sounds for the sonification.This submodule handles the actual generation of sound for the sonification, after parameterisation by the
Sourcesand musical choices dictated by theScore.Todo
Consolidate more common code into the
Generatorparent class.Support more Envelope and LFO types in the
playmethods (want pitch, volume and filter options for each)Check buffer length consistency for spectralizer - do we hit grid points?
Throw appropriate errors when rendering with unreasonable length and freq combinations
- class strauss.generator.Generator(params={}, samprate=48000)[source]
Bases:
objectGeneric generator Class, defining common code for child classes
Generators have common initialisation and methods that are defined by this parent class.
- samprate
Samples per second of audio stream (Hz)
- Type:
int
- audbuff
Samples per audio buffer
- Type:
int
- preset
Dictionary of parameters defining the generator.
- Type:
dict
- env_segment_curve(t, t1, y0, k)[source]
Formula for segments of the envelope function
Function to evaluate the segments of the envelope, allowing for curvature, i.e. concave & convex envelope segments.
- Parameters:
t (
float) – time of each sample along segmentt1 (
float) – time of segment endpointy0 (
float) – starting value of segmentk (
float) – curvature value of segment, from (-1,1), with positive values indicating concave and negative convex curvature.
- envelope(samp, params, etype='volume')[source]
Envelope function for modulating a single note
The envelope function takes the pre-defined envelope parameters for the specified envelope type and returns the envelope value at each sample. envelopes are defined by attack, decay, sustain and release (
'A','D','S' & 'R) values, as well as segment curvatures ('Ac','Dc', & 'Rc) and a normalisation'level'. See this article for a more detailed explanation of ADSR envelopes.
- Parameters:
samp (
array-like) – Audio sample indexparams (
dict) – Keys and values of generator parametersetype (optional ,
str) – type of envelope, indicating whichparamsgroup to read (i.e. ifetype='volume', read from :obj:`volume_envelope)
- lfo(samp, sampfrac, params, ltype='pitch')[source]
Low-Frequency oscillator (LFO)
This function takes the pre-defined LFO parameters (if switched on) for the specified LFO type and returns the LFO value at each sample. LFOs are defined by the same values as
strauss.generator.envelope(), with an additionaluseswitch, a waveform (wave, e.g.sine), an amplitude (amount), a frequncy in Hz (freq) a frequency shift in octaves (freq_shift) and aphase, either numerical in cycles or'random'to indicate randomised.Note
To modulate the frequency of an oscillator, use the
freq_shiftparameter, rather thanfreq
- Parameters:
samp (
array-like) – Audio sample indexsampfrac (
array-like) – Audio sample as fraction of total number of samplesparams (
dict) – Keys and values of generator parametersltype (optional ,
str) – type of LFO, indicating whichparamsgroup to read (i.e. ifltype='volume', read `from :obj:`pitch_envelope)- Returns:
amplitude of LFO at each input sample
- Return type:
v (
array-like)
- load_preset(preset='default')[source]
Load parameters from a preset YAML file.
Wrapper method for the
presets.synth.load_presetorpresets.sampler.load_presetfunctions. Always load thedefaultpreset first to ensure all parameters are defined, and then if necessary reload parameters defined bypreset
- Parameters:
preset (
str) – name of the preset. Built-in presets can be named directly and looks to import the preset from the<MODULE_PATH>/presets/<GENERATOR>/directory as<preset>.yml, where<GENERATOR>is either synth or sampler,<MODULE_PATH>is the path to the strauss module (i.e.strauss.__file__). Custom presets can also be loaded from<preset>.ymlifpresetrepresents a path containing file separators.
- modify_preset(parameters, cleargroup=[])[source]
Modify parameters within current preset
method allows user to tweak generator parameters directly, using a dictionary of parameters and their values. subgroups within the preset are represented as nested dictionaries.
- Parameters:
parameters (
dict) – keys and items are the preset parameter names and new values. Nested dictionaries are used to redefine grouped parameters, e.g.{'volume_envelope':{'A':0.5}}cleargroup (optional
list(str)) – if required, list of the group names to be completely reset (e.g. if defining newoscillatorsset for synth).
- noise(s, f, p)[source]
White noise oscillator
Note
fandphave no efffect for this oscillator, generating a random value for each sample.
- Parameters:
s (
array-like) – sample indexf (
float) – unusedp (
floatorstr) – unused- Returns:
values for each sample
- Return type:
v (
array-like)
- preset_details(term='*')[source]
Print the names and descriptions of presets
Wrapper for preset_details function. lists the name and description of built-in presets with names matching the search term.
- Parameters:
term (optional,
str) – name or glob term for built-inpreset (s)
- saw(s, f, p)[source]
Sawtooth-wave oscillator
- Parameters:
s (
array-like) – sample indexf (
float) – samples per cyclep (
floatorstr) – if numerical, phase in units of cycles,'random'indicates randomised.- Returns:
values for each sample
- Return type:
v (
array-like)
- sine(s, f, p)[source]
Sine-wave oscillator
- Parameters:
s (
array-like) – sample indexf (
float) – samples per cyclep (
floatorstr) – if numerical, phase in units of cycles,'random'indicates randomised.- Returns:
values for each sample
- Return type:
v (
array-like)
- class strauss.generator.Sampler(sampfiles, params=None, samprate=48000, sf_preset=None)[source]
Bases:
GeneratorSampler generator class
This generator class generates sound using pre-loaded audio samples, representing different notes. Presets define parameters controlling these defines attribute
self.gtype = 'sampler'.
- gtype
Generator type
- Type:
strTodo
Add zone mapping for samples (e.g. allow a sample to define a range of notes played at different speeds).
Support non-scientifically named notes? (e.g
'cymbal','snare').Have sample loading defined via the preset rather than the
sampfilesvariable?
- forward_back_loopsamp(s, start, end)[source]
Looping samples forward-backward alternately using indexing
From a list of samples and start and end loop-points, return a new list of samples that index the audio file samples to create a back and forth looping effect.
- Parameters:
s (
array-like) – Sample indexes for the duration of a source’s notestart (
int) – Sample index at which to start the loopend (
int) – Sample index at which to end the loop- Returns:
new sample indices to create a back and forth looping effect
- Return type:
s_new (
array-like)
- forward_loopsamp(s, start, end)[source]
Looping samples forward using indexing
From a list of samples and start and end loop-points, return a new list of samples that index the audio file samples to create a forward-looping effect.
- Parameters:
s (
array-like) – Sample indexes for the duration of a source’s notestart (
int) – Sample index at which to start the loopend (
int) – Sample index at which to end the loop- Returns:
new sample indices to create a forward-looping effect
- Return type:
s_new (
array-like)
- get_sfpreset_samples(sfpreset)[source]
Reading samples from a soundfont file along with metadata.
Read in the audio samples from a
.sf2file to populate available notes, mapping the MIDI key values to musical notes, scaling and tuning samples as appropriate.
- Parameters:
sf_preset (optional,
int) – preset to use. All .sf2 files should contain at least one preset. When given default None value, will print available presets and select the first preset. Note presets are 1-indexed.- Returns:
dictionary of data required to load soundfont samples in to the Sampler, including raw samples, sample_rate, original_pitch of the samples, the min_note and max_note in midi values to use the sample, and the sample_map, assigning each sample to a note.
- Return type:
sfpre_dict (
dict)
- load_samples()[source]
Load audio samples into the sampler.
Read audio samples in from a specified directory or via a dictionary of filepaths, generate interpolation functions for each, and assign them to a named note in scientific pitch notation (e.g.
'A4').Note
Notes are assigned based on a tag in the filename (see
Sampler), not by analysing the audio itself. If a tuned sample is tagged as the wrong note, this will carry over to the sonification. However, this allows non-pitched samples to be assigned notes and triggered.
- play(mapping)[source]
Play the sound for a given source.
Play a given source and return the sample values for combination into the overall sonification.
Note
mappingis a linear dictionary (not nested, as forstrauss.generator.modify_preset()) where group members are indicated using'/'notation (e.g.{'volume_envelope/A': 0.5, ...).
- Parameters:
mapping (
dict) – keys and items are generator parameter names and their values. This combines all the preset mapped parameters, overwritten by anySource-mapped parameters (represented as values or interpolation functions for static and evolving parameters, respectively). This is a linear dictionary (not nested, seestrauss.generator.modify_preset()) where group members are indicated using'/'notation (e.g.{'volume_envelope/A': 0.5, ...).
- reconstruct_samples(sfpre_dict)[source]
Interpolate, combine and resample soundfont samples for each note, and load into the Sampler.
- Parameters:
sfpre_dict (
dict) – dictionary of data required to load soundfont samples in to the Sampler, including raw samples, sample_rate, original_pitch of the samples, the min_note and max_note in midi values to use the sample, and the sample_map, assigning each sample to a note.- Returns:
output dictionary of mapped notes, with values of arrays of sample values at the samplerate of the Generator.
- Return type:
sampdict (
dict)
- class strauss.generator.Spectralizer(params=None, samprate=48000)[source]
Bases:
GeneratorSpectralizer generator class
This generator class synthesises sound from a spectrum input using an inverse Fast Fourier Transform (iFFT) algorithm. Defining a minimum and maximum frequency in Hz, input spectrum is interpolated between these points such that the output audio signal has the requested length. Phases are randomised to avoid phase correlations.
- gtype
Generator type
- Type:
strTodo
Add other synthesiser types, aside from additive (e.g. FM, vector, wavetable)?
- play(mapping)[source]
Play the sound for a given source.
Play a given source and return the sample values for combination into the overall sonification.
Note
mappingis a linear dictionary (not nested, as forstrauss.generator.modify_preset()) where group members are indicated using'/'notation (e.g.{'volume_envelope/A': 0.5, ...).
- Parameters:
mapping (
dict) – keys and items are generator parameter names and their values. This combines all the preset mapped parameters, overwritten by anySource-mapped parameters (represented as values or interpolation functions for static and evolving parameters, respectively). This is a linear dictionary (not nested, seestrauss.generator.modify_preset()) where group members are indicated using'/'notation (e.g.{'volume_envelope/A': 0.5, ...).
- spectrum_to_signal(spectrum, phases, new_nlen, mindx, maxdx, interp_type)[source]
Convert the input spectrum into sound signal
Performs the inverse fast fourier transform to produce spectral sonification.
- Parameters:
spectrum (
ndarray) – Values of the spectrum, ordered from high to low frequencyphases (
ndarray) – Array of values of [0,2*numpy.pi] representing the complex number argumentnew_nlen (
int) – Number of samples needed to enclose the output signal.mindx (
int) – Index in total Fourier transform represnting the minimum audio frequencymaxdx (
int) – Index in total Fourier transform represnting the maximum audio frequencyinterp_type (
str) – Interpolation approach, either “sample” interpolating between samples, or “preserve_power” where cumulative power is interpolated and then differentiated to avoid missing power.
- class strauss.generator.Synthesizer(params=None, samprate=48000)[source]
Bases:
GeneratorSynthesizer generator class
This generator class synthesises sound using mathmatically generated waveforms or ‘oscillators’, from a combination of oscillator methods defined in the parent class. The relative frequency, phase and amplitude of these oscillators are defined in the preset, and linearly combined to produce the sound. defines attribute
self.gtype = 'synth'.
- gtype
Generator type
- Type:
strTodo
Add other synthesiser types, aside from additive (e.g. FM, vector, wavetable)?
- combine_oscs(s, f)[source]
Evaluate and linearly combine oscillators.
- Parameters:
s (
array-like) – Sample indexf (
floatorstr) – If numerical, frequency in cycles per second, if string, note name in scientific pitch notation (e.g.'A4')- Returns:
values for each sample
- Return type:
tot (
array-like)
- modify_preset(parameters, clear_oscs=True)[source]
Synthesizer-specific wrapper for the modify_preset method.
This gives control over whether or not to clear the arbitrary number of oscillators for synthesizer.
- Parameters:
parameters (
dict) – keys and items are the preset parameter names and new values. Nested dictionaries are used to redefine grouped parameters, e.g.{'volume_envelope':{'A':0.5}}clear_oscs (optional,
bool) – if True, clear all oscillators from the existing preset. Turn off if just wishing to tweak non-oscillator parameters.
- play(mapping)[source]
Play the sound for a given source.
Play a given source and return the sample values for combination into the overall sonification.
Note
mappingis a linear dictionary (not nested, as forstrauss.generator.modify_preset()) where group members are indicated using'/'notation (e.g.{'volume_envelope/A': 0.5, ...).
- Parameters:
mapping (
dict) – keys and items are generator parameter names and their values. This combines all the preset mapped parameters, overwritten by anySource-mapped parameters (represented as values or interpolation functions for static and evolving parameters, respectively). This is a linear dictionary (not nested, seestrauss.generator.modify_preset()) where group members are indicated using'/'notation (e.g.{'volume_envelope/A': 0.5, ...).
- setup_oscillators()[source]
Setup and consolidate oscs into a two-variable function.
Reads the parameterisation of each oscillator from the preset, specifying their waveform (
wave), relative amplitude (level), detuning in cents (det) andphase, either a number in units of cycles, or a string specifying randomisation ('random'). Sets theself.generatemethod, using theself.combine_oscs.Note
This is deprecated and will likely be removed from future versions
- strauss.generator.detuned_saw(samples, freqsamp, oscdets=[1, 1.005, 0.995])[source]
DEPRECATED CODE: Three oscillator sawtooth wave generator with slight detuning for texture
- strauss.generator.forward_back_loopsamp(s, start, end)[source]
Produce array of sample indices for looping a sample forward-back.
Sample indices between values start and end that will loop the sample such that it loops “forward-back”, i.e. start, start+1, …, end-1, end, end-1, …, start+1, start, start+1, … etc. … etc.
- Parameters:
s (
ndarray) – array of input sample indicesstart (
int) – Index of sample after which looping should commenceend (
int) – Index of sample after which audio loops- Returns:
array of output sample indices
- Return type:
out (
ndarray)
- strauss.generator.forward_loopsamp(s, start, end)[source]
Produce array of sample indices for looping a sample forward.
Sample indices between values start and end that will loop the sample such that it loops “forward”, i.e. start, start+1, …, end-1, end, start, … etc.
- Parameters:
s (
ndarray) – array of input sample indicesstart (
int) – Index of sample after which looping should commenceend (
int) – Index of sample after which audio loops- Returns:
array of output sample indices
- Return type:
out (
ndarray)
Channels
channelssubmodule representing the output audio channels.This submodule defines objects relevant to the output audio channels, including the
audio_channelswhich defines arrays of microphone objects that are channeled to different speakers in the sonification output.
- class strauss.channels.audio_channels(setup='stereo', custom_setup={})[source]
Bases:
objectRepresenting output audio channels.
Data object representing the output channels of the sonification for preset common audio setups, or a custom setup. Stores an array of
micobjects for each output channel.
- Parameters:
setup (
str) – Type of audio setup. Supported options are"mono","stereo","5.1"and"7.1", or"custom".custom_setup (
dict) – Dictionary defining a customised audio setup, containing keys for"azimuths","types"and"labels", containing lists parameterising the first three arguments of themicobject, respectively in the order of their channel index. Also optionally an forder list to unscramble any channel order scrambling done by ffmpeg processing in the sonification sae routines (this may need to be found empirically, awaiting better multichannel save routine).- Raises:
Exception – If custom requested but no parameters provided, or custom parameters provided without requesting a custom setup.
- plot_antenna()[source]
Plot antennae patterns for chosen audio setup
Make a
matplotlibfigure object, representing a radial plot demonstrating the antennae patterns of each channel
- Returns:
figure object that can be shown or saved using the standard
matplotlibroutines.- Return type:
fig (
matplotlib.pyplot.figure)
- setup_channels(azimuths, types, labels, orders=None, degrees=None)[source]
initialise audio channel setup for lists of properties
Subroutine for setting up the audio_channels as arrays of
micobjects, setting theself.micslist attribute to theaudio_channels
- class strauss.channels.mic(azimuth, mic_type='directional', label='C', channel=1, order=None, degree=None)[source]
Bases:
objectMicrophone / sound detector object
This class represents a microphone, or sound-detector, corresponding to a particular output channel for audio spatialisation in the sonicfication.
- Parameters:
azimuth (
float) – Angular position of the microphone on the horizontal plane, from 0 to 2pi with 0.5 pi being to the left and 1.5 pi being to the right. In the special case of ambisonic, this is instead an index corresponding to the Ambisonic Channel Number (ACN)mic_type (
str) – Type of microphone, choose from"directional"(collects using a cardioid antenna pattern),"omni"(collects sound from all directions equally) and"mute"(collects no sound, useful for e.g. muting auxillary channels)label (
str) – A label for the micchannel (
int) – channel ordering in the output (starting from 0 e.g. stereo L=0, R=1)- Raises:
Exception – if mic_type not in allowed options
Sonification
sonification: generate sonification, combining submodules.This Submodule handles the combining of all the constituent subroutines into a single
sonificationobject that can then render and output/save the resultant sonification. This handles feeding of information betweenstraussmodules, including taking thesourcesmapping, applying any musical constraints fromscorerunning thegeneratorsto make sound and combining them into the output channels for the overall spatialised sonificiation.Todo
Delegate more musical process to the
scoremodule
- class strauss.sonification.Sonification(score, sources, generator, audio_setup='stereo', caption=None, samprate=48000, ttsmodel=None)[source]
Bases:
objectRepresenting the overall sonification
This class combines the data sources, musical score constraints and generator together to generate and render the ultimate sonification for saving or playing in the
jupyter-notebookenvironmentTodo
Support custom audio setups here too.
- hear()[source]
Play audio directly to the sound device, for command-line playback.
If available, use the
sounddevicemodule to stream the sonification to the sound device directly (speakers, headphones, etc.) via the underlyingPortAudioC-library. if unavaialable, raise error.Todo
Add more options to control the streamed audio
- notebook_display(show_waveform=True)[source]
plot the waveforms and embed player in the notebook
Show waveforms and embed an audio player in the python notebook for direct playback. the notebook player only supports up to stereo, so if more than two channels, only the first two are used as left and right.
- render(downsamp=1)[source]
Render the sonification.
Generates the sonification by running the Synthesizer
play()or Samplerplay()functions, and combining these into the output channel streams using any spatialisation for the specifiedaudio_channels.
- Parameters:
downsamp (optional,
int) – Optionally downsample sources for multi-source sonifications for a quicker test render by some integer factor.
- save(fname, master_volume=1.0, embed_caption=True)[source]
Save render as a combined multi-channel wav file
Can use this function to save sonification of any audio_setup to a 32-bit depth WAV using scipy.io.wavfile
- Parameters:
fname (
str)master_volume (
float) – peak, from 0-1embed_caption (
bool) – at the start of the output audioTodo
Raise scipy issue if common 24-bit WAV can be supported
- save_combined(fname, ffmpeg_output=False, master_volume=1.0)[source]
Save render as a combined multi-channel wav file
Can use this function to save sonification of any audio_setup, using ffmpeg processing, and unscrampling to the correct channel order.
- Parameters:
fname (
str)ffmpeg_output (
bool) – output to screenmaster_volume (
float) – peak, from 0-1
Ancillary Modules
These are modules intended for internal use by the strauss module
Utilities
The
utilitiessubmodule: useful functions forstraussThis submodule is for useful utility functions used by other
straussmodules. Generally these are not intended for direct use by the user.
- class strauss.utilities.Capturing(iterable=(), /)[source]
Bases:
listContext manager for handling stdout (see https://stackoverflow.com/a/16571630)
- class strauss.utilities.NoSoundDevice(err)[source]
Bases:
objectDrop-in replacement for sounddevice module if not working, so we can still use other functionality.
- err
Error message from trying to import sounddevice
- Type:
Exception
- strauss.utilities.const_or_evo(x, t)[source]
If x is callable, return x(t), else return x
- Parameters:
x – input value, either a numerical value or a
function
t (numerical) – values to evaluate x function
- strauss.utilities.const_or_evo_func(x)[source]
If x is callable, return x, else provide a function that just returns x
- Parameters:
x – input value, either a numerical value or a
function
- strauss.utilities.linear_to_nested_dict_reassign(fromdict, todict)[source]
Iterate through a linear dictionary to reassign nested values using keypaths (d1[‘a/b/c’] -> d2[‘a’][‘b’][‘c’], d1[‘a’]->d2[‘a’])
- Parameters:
fromdict (
dict) – Dictionary containing values to assigntodict (
dict) – Dictionary containing values to be reassigned
- strauss.utilities.nested_dict_fill(fromdict, todict)[source]
Recurse through dictionaries and sub-dictionaries in fromdict and assign to any entries missing from todict
- Parameters:
fromdict (
dict) – Dictionary containing values to assign
- todict (
dict): Dictionary containing values tobe reassigned
- strauss.utilities.nested_dict_idx_reassign(fromdict, todict, idx)[source]
Recurse through dictionaries and sub-dictionaries of iterables in fromdict and index value idx to assign or replact value in todict
- Parameters:
fromdict (
dict) – Dictionary containing values to assigntodict (
dict) – Dictionary containing values to be reassignedidx (
dict) – Index value for retrieving value from iterables
- strauss.utilities.nested_dict_reassign(fromdict, todict)[source]
Recurse through dictionaries and sub-dictionaries in fromdict and reassign equivalent values in todict
- Args
- fromdict (
dict): Dictionary containing valuesto assign
- todict (
dict): Dictionary containing valuesto be reassigned
- strauss.utilities.reassign_nested_item_from_keypath(dictionary, keypath, value)[source]
Reassign item in a nested dictionary to value using keypath syntax, to traverse multiple dictionaries
- Parameters:
dictionary (
dict) – dict object to reassign values withinkeypath (
str) – Using filepath syntax on given OS to traverse dictionary, i.e ‘a/b/c’ (‘abc’) corresponds to dict[‘a’][‘b’][‘c’] on Unix (Windows).value – value to reassign dictionary value with
- strauss.utilities.resample(rate_in, samprate, wavobj)[source]
Resample audio from original samplerate to required samplerate
- Parameters:
rate_in (
int)samprate (
int)wavobj (
tuple)function (by scipy.io.wavfile)
- Returns:
new_wavobj (
tuple) as wavobj, with new sample rate and resampled sample values
- strauss.utilities.rescale_values(x, oldlims, newlims)[source]
Rescale x values defined by limits oldlims to new limits newlims
- Parameters:
x (of) – Array of input values
oldlims (
tuple) – tuple representing the original limitsx
newlims (
tuple) – tuple representing the new limits- Returns:
Rescaled array
- Return type:
x_rs (array-like)
Stream
The
streamsubmodule: representing the sound signalContaining the
Streamclass to house theSonificiationaudio signal for each channel in theChannelsobject. This can be split into uniform segments or buffers via theBuffersobject, for processing.Todo
implement filter Q-parameter mapping
- class strauss.stream.Buffers(stream, bufflength=0.1)[source]
Bases:
objectAudio buffers split into uniform discrete chunks or ‘buffers’.
Audio ~:class:stream.Stream as a discrete sequence of individual ‘buffers’ of fixed duration (number of samples). This allows time varying operations in frequency space, such as signal filtering. Buffers are tiled in a ‘brickwork’ fashion so they always overlap with another buffer.
- fade
Window function for recombining overlapping buffers
- Type:
ndarray
- nsamp_padstream
Number of samples needed to split the stream into discrete buffers of chosen length
- Type:
int
- nsamp_pad
Number of additional samples needed to add to the original Stream size in this case
- Type:
int
- buffs_tile
2d array of buffers completely enclosing the stream (number of buffers x samples per buffer)
- Type:
ndarray
- buffs_olap
allowing for cross fading
- Type:
ndarray
- to_stream()[source]
Reconstruct stream by cross-fading buffers
Takes the self.buffs_tile and self.buffs_olap arrays and using the self.fade window function, add overlapping sample values together to yield a 1d array of samples.
- Returns:
- 1d array of sample values representing the
new audio signal for the parent Stream.
- Return type:
out (
ndarray)
- class strauss.stream.Stream(length, samprate=44100, ltype='seconds')[source]
Bases:
objectStream object representing audio samples.
Houses audio samples and associates metadata representing the actual audio signal produced by the Generator class and output via the audio_channels class.
- samprate
Samples per second of audio stream (Hz)
- Type:
int
- length
Duration of the stream in seconds
- Type:
float
- values
Values of individual samples
- Type:
ndarray
- samples
Indices of each sample
- Type:
ndarray
- samptype
Time in seconds each sample occurs
- Type:
ndarray
- bufferize(bufflength=0.1)[source]
Wrapper to initialise Buffers subclass
- Parameters:
bufflength (optional,
float) – duration in seconds of each buffer to be generated
- consolidate_buffers()[source]
Wrapper to reassign stream values to consolidated buffers
See
to_stream()
- filt_sweep(ffunc, fmap, qmap=<function Stream.<lambda>>, flo=20, fhi=22050.0, qlo=0.5, qhi=10)[source]
Apply time varying filter to buffered stream
- Parameters:
ffunc (function) – function that applies filter
fmap (function) – mapping function representing filter cutoff sweep
qmap (optional, function) – mapping function for a filters Q parameter
flo (optional,
float) – lowest frequency of sweep in Hz, default 20fhi (optional,
float) – lowest frequency of sweep in Hz, default 22.05 kHzqlo (optional,
float) – lowest ‘Q’ value of sweep, default 0.5qhi (optional,
float) – lowest frequency of sweep, default 10
Notes
The
notessubmodule: translating musical note representationsThis submodule contains functions for translating between different representations of musical notes or musical chords, and representative sound frequencies and MIDI notes.
- strauss.notes.tuneC0
The frequency in Hz of the
C0musical note
- Type:
float
- strauss.notes.notecount
Semitone offset above C in an octave
- Type:
int
- strauss.notes.notesharps
Names of musical notes using sharp notation
- Type:
list
- strauss.notes.noteflats
Names of musical notes using flat notation.
- Type:
list
- strauss.notes.semitone_dict
Dictionary of note names to semitone offsets above C.
- Type:
dict
- strauss.notes.chord_notes(chordname, rootoct=3)[source]
Takes name of a chord and root octave to generate a valid chord voicing as a list of note names, using the pychord library
- Parameters:
chordname (
str) – Standard chord name, e.g. ‘A7’ or ‘Dm7add9’ etc.rootoct (
int) – Octave number- Returns:
list of note names constituting chord
- Return type:
out (
list)
- strauss.notes.mkey_to_note(val)[source]
Take MIDI key value and return the note name in scientific notation
- Parameters:
val (
int) – MIDI key value- Returns:
- scientific pitch name, in format
<note><octave>, e.g. ‘E3’ or ‘F#2’
- Return type:
out (
str)
- strauss.notes.parse_chord(chordname, rootoct=3)[source]
Takes name of a chord and root octave to generate a valid chord voicing as an array of frequencies in Hz, using the pychord library
- Parameters:
chordname (
str) – Standard chord name, e.g. ‘A7’ or ‘Dm7add9’ etc.rootoct (
int) – Octave number- Returns:
- out (
ndarray) array of frequencies constitutingchord
- strauss.notes.parse_note(notename)[source]
Takes scientific pitch name and returns frequency in Hz. Flat and sharp values supported. Assumes equal temperament and A4 = 440 Hz tuning (ISO 16)
- Parameters:
notename (
str) – scientific pitch name, in format <note><octave>, e.g. ‘Ab4’, ‘E3’ or ‘F#2’- Returns:
Frequency of note in Hertz
- Return type:
out (numerical)
Filters
The
filterssubmodule: containing audio filter functionsThese are audio filters that can be applied to the audio signal in frequency space to attenuate (filter out) frequencies. These can be applied to individual
Buffersas an evolvable parameter.Todo
Support More Filter Types
Implement resonance or ‘Q’ variation
- strauss.filters.HPF1(data, cutoff, q, order=5)[source]
High-pass filter data array given cutoff, q and HPF order
- Parameters:
data (array-like) – Array containing signal for filtering
cutoff (
float) – Cutoff frequencyq (
float) – Filter quality-factor or ‘Q’ valueorder (
int) – polynomial order of filter function
- Return
y (array-like): Filtered array for output
- strauss.filters.LPF1(data, cutoff, q, order=5)[source]
Low-pass filter data array given cutoff, q and LPF order
- Parameters:
data (array-like) – Array containing signal for filtering
cutoff (
float) – Cutoff frequencyq (
float) – Filter quality-factor or ‘Q’ valueorder (
int) – polynomial order of filter function
- Return
y (array-like): Filtered array for output
Text-to-Speech
The
tts_captionsubmodule: tool for generating spoken captionsThis uses text-to-speech via the the
TTSmodule to allow captions represented as strings to be converted to spoken audio to precede the sonification.
- strauss.tts_caption.getVoices(info=False)[source]
Get available voices for text-to-speech.
When info=True, this prints out information for each voice option.
- Args:
info (
bool): Print out voice information when True, by default False voices (list): List ofpyttsx3.voice.Voiceobjects ordictobjects.
- strauss.tts_caption.render_caption(caption, samprate, model, caption_path)[source]
The render_caption function generates an audio caption from text input and writes it as a wav file. If the sample rate of the model is not equal to that passed from sonification.py, it resamples to the correct rate and re-writes the file.
If Coqui-AI is installed, text from user input is converted with text-to- speech software from Coqui-AI - https://pypi.org/project/TTS/ . You can view publicly available voice models with ‘TTS.list_models()’
If Coqui-AI is not installed but pyttsx3 (https://pypi.org/project/pyttsx3/) is installed, text from user input is converted offline using pyttsx3.
Note: STRAUSS checks if Coqui-AI is available. If it is,
ttsModeis set tocoqui-ai. If it is unavailable, STRAUSS checks whether pyttsx3 is available. If it is,ttsModeis set topyttsx3.
- Parameters:
caption (
str) – script to be spoken by the TTS voicesamprate (
int) – samples per secondmodel (
strfor Coqui-AI;dictfor pyttsx3) – for Coqui-AI: valid name of TTS voice from the underlying TTS module; for pyttsx3: dictionary with keys of ‘rate’ (percent of speed, signed int16), ‘volume’ (float from 0 to 1), and/or ‘voice’ (the voice ‘id’ that can be chosen from the list given by the TTS.list_models() function).caption_path (
str) – filepath for spoken caption output