Skip to content

loristrck.util

Utility functions to manipulate / transform partials and list of partials

Example 1

Select a group of partials and render the selection as sound

import loristrck as lt
partials = lt.read_sdif(...)
selected, _ = lt.util.select(partials, minbps=2, mindur=0.005, 
                             minamp=-80, maxfreq=17000)
lt.util.patials_render(partials, 44100, "selected.wav")

Class Description
PartialIndex Create an index to accelerate finding partials
Function Description
breakpoints_extend Given a list of breakpoints, extend each to form a partial of the given dur
breakpoints_to_chord Convert breakpoints to a list of (notename, freq, amplitude_db
chord_to_partials Generate partials from the given chord
concat Concatenate multiple Partials to produce a new one.
db2amp Convert amplitude in dB to linear amplitude
db2ampnp Convert amplitude in dB to linear amplitude for a numpy array
estimate_sampling_interval Estimate a sampling interval (dt) for this spectrum
filter Similar to select, but returns a generator yielding only selected partials
i2r Interval to ratio
kaiser_length Returns the length in samples of a Kaiser window from the desired main lobe width.
loudest Get the loudest N partials.
matrix_save Save the raw data mtx.
meanamp Returns the mean amplitude of a partial
meanfreq Returns the mean frequency of a partial
pack Pack non-simultenous partials into longer partials with silences in between.
partial_at Evaluates partial p at time t
partial_crop Crop partial at times t0, t1
partial_energy Integrate the partial amplitude over time.
partial_fade Apply a fadein / fadeout to this partial so that the first and last
partial_sample_at Sample a partial p at given times
partial_sample_regularly Sample a partial p at regular time intervals
partial_timerange Return begin and endtime of partial
partials_at Sample the partials which satisfy the given conditions at time t
partials_between Return the partials present between t0 and t1
partials_render Render partials as a soundfile
partials_sample Samples the partials between times t0 and t1 with sampling period dt
partials_save_matrix Packs short partials into longer partials and saves the result as a matrix
partials_stretch Stretch the partials in time by a given constant factor
partials_timerange Return the timerange of the partials: (begin, end)
partials_transpose Transpose the partials by a given interval
plot_partials Plot the partials using matplotlib
select Selects a seq. of partials matching the given conditions
sndread Read a sound file.
sndreadmono Read a sound file as mono.
sndwrite Write the samples to a soundfile
wavwrite Write samples to a wav-file (see also sndwrite) as float32 or float64
write_sdif Write a list of partials as SDIF.

PartialIndex

def () -> None

Create an index to accelerate finding partials

After creating the PartialIndex, each call to partialindex.partials_between should be faster than simply calling partials_index since the unoptimized function needs to always start a linear search from the beginning of the partials list.

Note

The index is only valid as long as the original partial list is not modified


Summary

Method Description
init -
partials_between Returns the partials which are defined within the given time range


Methods

__init__

def __init__(self, partials: list[np.ndarray], dt: float = 1.0) -> None

Args

  • partials (list[np.ndarray]): the partials to index
  • dt (float): the time resolution of the index. The lower this value the faster each query will be but the slower the creation of the index itself (default: 1.0)

partials_between

def partials_between(self, t0: float, t1: float) -> list[np.ndarray]

Returns the partials which are defined within the given time range

Args

  • t0 (float): the start of the time interval
  • t1 (float): the end of the time interval

Returns

    (list[np.ndarray]) a list of partials present during the given time range


breakpoints_extend

def breakpoints_extend(bps, dur: float) -> list[np.ndarray]

Given a list of breakpoints, extend each to form a partial of the given dur

Example

samples, sr = sndreadmono("...")
partials = analyze(samples, sr, resolution=50)
selected = partials_between(partials, 0.5, 0.5)
breakpoints = partials_at(selected, 0.5, maxcount=4)
print(breakpoints_to_chord(breakpoints))
partials_render(breakpoints_extend(breakpoints, 4), outfile="chord.wav", open=True)

Args

  • bps: a list of breakpoints, as returned by partials_at
  • dur (float): the duration of the resulting partial

breakpoints_to_chord

def breakpoints_to_chord(bps, A4: int = 442) -> tuple[str, float, float]

Convert breakpoints to a list of (notename, freq, amplitude_db

Args

  • bps: the breakpoints, as returned, for example, by partials_at
  • A4 (int): (default: 442)

chord_to_partials

def chord_to_partials(chord: list[tuple[float, float]], dur: float, 
                      fade: float = 0.1, startmargin: float = 0.0, 
                      endmargin: float = 0.0) -> list[np.ndarray]

Generate partials from the given chord

Args

  • chord (list[tuple[float, float]]): a list of (freq, amp) tuples
  • dur (float): the duration of the partials
  • fade (float): the fade time (default: 0.1)
  • startmargin (float): ?? endmargin ?? (default: 0.0)
  • endmargin (float): (default: 0.0)

Returns

    (list[np.ndarray]) a list of partials


concat

def concat(partials: list[np.ndarray], fade: float = 0.005, 
           edgefade: float = 0.0) -> np.ndarray

Concatenate multiple Partials to produce a new one.

Assumes that the partials are non-overlapping and sorted

Note

partials need to be non-simultaneous and sorted

Args

  • partials (list[np.ndarray]): a seq. of partials (each partial is a 2D-array)
  • fade (float): fadetime to apply at the end/beginning of each concatenated partial (default: 0.005)
  • edgefade (float): a fade to apply at the beginning of the first and at the end of the last partial (default: 0.0)

Returns

    (np.ndarray) a numpy array representing the concatenation of the given partials


db2amp

def db2amp(x: float) -> float

Convert amplitude in dB to linear amplitude

Args

  • x (float): the value in dB to convert to amplitude

Returns

    (float) the amplitude of x as linear amplitude


db2ampnp

def db2ampnp(x: np.ndarray) -> np.ndarray

Convert amplitude in dB to linear amplitude for a numpy array

Args

  • x (np.ndarray): the dB values to convert

Returns

    (np.ndarray) the corresponding linear amplitudes


estimate_sampling_interval

def estimate_sampling_interval(partials: list[np.ndarray], maxpartials: int = 0, 
                               percentile: int = 25, ksmps: int = 64, 
                               sr: int = 44100) -> float

Estimate a sampling interval (dt) for this spectrum

The usage is to find a sampling interval which neither oversamples nor undersamples the partials for a synthesis strategy based on blocks of computation (like in csound, supercollider, etc, where each ugen is given a buffer of samples to fill instead of working sample by sample)

Args

  • partials (list[np.ndarray]): a list of partials
  • maxpartials (int): if given, only consider this number of partials to calculate dt (default: 0)
  • percentile (int): ??? (default: 25)
  • ksmps (int): samples per cycle used when rendering. This is used in the estimation to prevent oversampling (default: 64)
  • sr (int): the sample rate used for playback, used together with ksmps to estimate a useful sampling interval (default: 44100)

Returns

    (float) the most appropriate sampling interval for the data and the playback conditions


filter

def filter(partials: list[np.ndarray], mindur: float = 0.0, mindb: int = -120, 
           maxfreq: int = 20000, minfreq: int = 0, minbps: int = 1, 
           t0: float = 0.0, t1: float = 0.0) -> Any

Similar to select, but returns a generator yielding only selected partials

Args

  • partials (list[np.ndarray]): the partials to filter
  • mindur (float): the min. duration of a partial (default: 0.0)
  • mindb (int): the min. amplitude, in dB (default: -120)
  • maxfreq (int): the max. frequency (default: 20000)
  • minfreq (int): the min. frequency (default: 0)
  • minbps (int): the min. number of breakpoints (default: 1)
  • t0 (float): the start time (default: 0.0)
  • t1 (float): the end time (default: 0.0)

Returns

    an iterator over the partials which fulfill these conditions


i2r

def i2r(interval: float) -> float

Interval to ratio

Args

  • interval (float): the interval to convert to a ratio

Returns

    (float) the ratio corresponding to the given interval (2 corresponds to an interval of an octave, 12)


kaiser_length

def kaiser_length(width: float, sr: int, atten: int) -> int

Returns the length in samples of a Kaiser window from the desired main lobe width.

Note

computeLength

Compute the length (in samples) of the Kaiser window from the desired (approximate) main lobe width and the control parameter. Of course, since the window must be an integer number of samples in length, your actual lobal mileage may vary. This equation appears in Kaiser and Schafer 1980 (on the use of the I0 window class for spectral analysis) as Equation 9. The main width of the main lobe must be normalized by the sample rate, that is, it is a fraction of the sample rate.

Args

  • width (float): the width of the main lobe in Hz
  • sr (int): the sample rate, in samples / sec
  • atten (int): the attenuation in possitive dB

Returns

    (int) the length of the window, in samples


loudest

def loudest(partials: list[np.ndarray], N: int) -> list[np.ndarray]

Get the loudest N partials.

If N is not given, all partials are returned, sorted in declining energy

The returned partials will be sorted by declining energy (integrated amplitude)

Args

  • partials (list[np.ndarray]): the partials to select from
  • N (int): the number of partials to select

Returns

    (list[np.ndarray]) the loudest N partials


matrix_save

def matrix_save(data: np.ndarray, outfile: str, bits: int = 32, 
                metadata: dict[str, Any] = None) -> None

Save the raw data mtx.

The data is saved either as a .mtx or as a .npy file.

The mtx file format

The mtx is an ad-hoc format where a float-32 wav file is used to store binary data. This .wav file is not a real soundfile, it is used as a binary storage format. A header is always included, with the data [headerSize, numRows, numColumns, ...] headerSize indicates the offset where the data starts. The data itself is saved flat, starting at that offset. To reconstruct in python, do:

import loristrck as lt
# discard sr, it has no meaning in this context
raw, _ = lt.sndread("mydata.mtx")
datastart = raw[0]
numrows = raw[1]
numcols = raw[2]
data = raw[datastart:]
data.shape = (numrows, numcols)

The .npy format is defined by numpy here: https://numpy.org/doc/stable/reference/generated/numpy.lib.format.html#module-numpy .lib.format

The data data is a 1D or a 2D numpy array.

Example

import loristrck as lt
partials = lt.read_sdif(path_to_sdif)
tracks = lt.pack(partials)
dt = 64/44100
m = lt.partials_sample(tracks, dt)
matrix_save(m, "out.mtx")

Args

  • data (np.ndarray): a 2D-matrix as returned by partials_sample
  • outfile (str): the path to the resulting output file. The format should be .mtx or .npy
  • bits (int): 32 or 64. 32 bits should be enough (default: 32)
  • metadata (dict[str, Any]): if given, it is included in the wav metadata and all numeric values are included in the data itself (default: None)

meanamp

def meanamp(partial: np.ndarray) -> float

Returns the mean amplitude of a partial

Args

  • partial (np.ndarray): a numpy 2D-array representing a Partial

Returns

    (float) the average amplitude


meanfreq

def meanfreq(partial: np.ndarray, weighted: bool = False) -> float

Returns the mean frequency of a partial

Optionally, frequencies can be weighted by the amplitude of the breakpoint so that louder parts contribute more to the average frequency as softer ones

Args

  • partial (np.ndarray): the partial to evaluate
  • weighted (bool): if True, weight the frequency by the amplitude (default: False)

Returns

    (float) the average frequency


pack

def pack(partials: list[np.ndarray], maxtracks: int = 0, gap: float = 0.01, 
         fade: float = -1.0, acceptabledist: float = 0.1, minbps: int = 2
         ) -> tuple[list[np.ndarray], list[np.ndarray]]

Pack non-simultenous partials into longer partials with silences in between.

These packed partials can be used as tracks for resynthesis, minimizing the need of oscillators.

Note

Amplitude is always faded out between partials

See also: partials_save_matrix

Args

  • partials (list[np.ndarray]): a list of arrays, where each array represents a partial, as returned by analyze
  • maxtracks (int): if > 0, sets the maximum number of tracks. Partials not fitting in will be discarded. Consider living this at 0, to allow for unlimited tracks, and limit the amount of active streams later on (default: 0)
  • gap (float): minimum gap between partials in a track. Should be longer than 2 times the sampling interval, if the packed partials are later going to be resampled. (default: 0.01)
  • fade (float): apply a fade to the partials before joining them. If not given, a default value is calculated (default: -1.0)
  • acceptabledist (float): instead of searching for the best possible fit, pack two partials together if they are near enough (default: 0.1)
  • minbps (int): the min. number of breakpoints for a partial to the packed. Partials with less that this number of breakpoints are filtered out (default: 2)

Returns

    (tuple[list[np.ndarray], list[np.ndarray]]) a tuple (tracks, unpacked partials)


partial_at

def partial_at(p: np.ndarray, t: float, extend: bool = False
               ) -> np.ndarray | None

Evaluates partial p at time t

Args

  • p (np.ndarray): the partial, a 2D numpy array
  • t (float): the time to evaluate the partial at
  • extend (bool): should the partial be extended to -inf, +inf? If True, querying a partial outside its boundaries will result in the values at the boundaries. Otherwise, None is returned (default: False)

Returns

    (np.ndarray | None) with columns (time, freq, amp, bw). Returns None if the array is not defined at the given time


partial_crop

def partial_crop(p: np.ndarray, t0: float, t1: float) -> np.ndarray

Crop partial at times t0, t1

Note

  • Returns p if p is included in the interval t0-t1
  • Returns None if partial is not defined between t0-t1
  • Otherwise crops the partial at t0 and t1, places a breakpoint at that time with the interpolated value

Args

  • p (np.ndarray): the partial
  • t0 (float): the start time
  • t1 (float): the end time

Returns

    (np.ndarray) if the partial is not defined within the given time constraints)


partial_energy

def partial_energy(partial: np.ndarray) -> float

Integrate the partial amplitude over time.

Serves as measurement for the energy contributed by the partial.

Example

Select loudest partials within the range 50 Hz - 6000 Hz

import loristrck as lt
partials = lt.read_sdif("path.sdif")
partials2 = lt.util.select(partials, minfreq=50, maxfreq=6000, 
                           minbps=4, mindur=0.005)
sorted_partials = sorted(partials2, key=lt.util.partial_energy, reverse=True)
loudest = sorted_partials[:100]
lt.util.plot_partials(loudest)

Args

  • partial (np.ndarray): the partial to calculate its energy from

Returns

    (float) the energy of this partial (the integral of amplitude over time)


partial_fade

def partial_fade(partial: np.ndarray, fadein: float = 0.0, fadeout: float = 0.0
                 ) -> np.ndarray

Apply a fadein / fadeout to this partial so that the first and last

breakpoints have an amplitude = 0

This is only applied if the partial starts or ends in non-zero amplitude

Args

  • partial (np.ndarray): the partial to fade
  • fadein (float): the fadein time. If 0 and the first breakpoint has a non-zero amplitude, zero the first amplitude in the partial (default: 0.0)
  • fadeout (float): the fadeout time. If 0 and the last breakpoint has a non-zero aplitude, zero the last amplitude in the partial. (default: 0.0)

Returns

    (np.ndarray) the faded partial


partial_sample_at

def partial_sample_at(p: np.ndarray, times: np.ndarray) -> np.ndarray

Sample a partial p at given times

Args

  • p (np.ndarray): a partial represented as a 2D-array with columns times, freqs, amps, phases, bws
  • times (np.ndarray): the times to evaluate partial at

Returns

    (np.ndarray) a partial (2D-array with columns times, freqs, amps, phases, bws)


partial_sample_regularly

def partial_sample_regularly(p: np.ndarray, dt: float, t0: float = -1.0, 
                             t1: float = -1.0) -> np.ndarray

Sample a partial p at regular time intervals

Args

  • p (np.ndarray): a partial represented as a 2D-array with columns times, freqs, amps, phases, bws
  • dt (float): sampling period
  • t0 (float): start time of sampling (default: -1.0)
  • t1 (float): end time of sampling (default: -1.0)

Returns

    (np.ndarray) a partial (2D-array with columns times, freqs, amps, phases, bws)


partial_timerange

def partial_timerange(partial: np.ndarray) -> tuple[float, float]

Return begin and endtime of partial

Args

  • partial (np.ndarray): the partial to query

Returns

    (tuple[float, float]) the start and end time


partials_at

def partials_at(partials: list[np.ndarray], t: float, maxcount: int = 0, 
                mindb: int = -120, minfreq: int = 10, maxfreq: int = 22000
                ) -> list[np.ndarray]

Sample the partials which satisfy the given conditions at time t

Args

  • partials (list[np.ndarray]): the partials analyzed. The partials should be present at the given time (after calling partials_between or PartialIndex.partials_between)
  • t (float): the time in seconds
  • maxcount (int): the max. partials to detect, ordered by amplitude (0=all) (default: 0)
  • mindb (int): the min. amplitude a partial has to have at t in order to be counted (default: -120)
  • minfreq (int): only partials with a freq. higher than this (default: 10)
  • maxfreq (int): only partials with a freq. lower than this (default: 22000)

Returns

    (list[np.ndarray]) the breakpoints at time t which satisfy the given conditions. Each breakpoint is a numpy array with [freq, amp, phase, bandwidth]


partials_between

def partials_between(partials: list[np.ndarray], t0: float = 0.0, 
                     t1: float = 0.0) -> list[np.ndarray]

Return the partials present between t0 and t1

This function is not optimized and performs a linear search over the partials. If this function is to be called repeatedly or within a performance relevant section, use PartialIndex instead

Args

  • partials (list[np.ndarray]): a list of partials
  • t0 (float): start time in secs (default: 0.0)
  • t1 (float): end time in secs (default: 0.0)

Returns

    (list[np.ndarray]) the partials within the time range (t0, t1)


partials_render

def partials_render(partials: list[np.ndarray], outfile: str, sr: int = 44100, 
                    fadetime: float = -1.0, start: float = -1.0, 
                    end: float = -1.0, encoding: str = None) -> None

Render partials as a soundfile

See Also: synthesize

Args

  • partials (list[np.ndarray]): the partials to render
  • outfile (str): the outfile to write to. If not given, a temporary file is used
  • sr (int): samplerate to render with (default: 44100)
  • fadetime (float): fade partials in/out when they don't end in a 0-amp bp (default: -1.0)
  • start (float): start time of render (default: start time of spectrum) (default: -1.0)
  • end (float): end time to render (default: end time of spectrum) (default: -1.0)
  • encoding (str): if given, the encoding to use (default: None)

partials_sample

def partials_sample(partials: list[np.ndarray], dt: float = 0.002, 
                    t0: float = -1, t1: float = -1, maxactive: int = 0, 
                    interleave: bool = True
                    ) -> np.ndarray | tuple[np.ndarray, np.ndarray, np.ndarray]

Samples the partials between times t0 and t1 with sampling period dt

To be used in connection with pack, which packs short non-simultaneous partials into longer ones. The result is a 2D matrix representing the partials.

Sampling times is calculated as: times = arange(t0, t1+dt, dt)

If interleave is True, it returns a big matrix of format

[[t0, f0, amp0, bw0, f1, amp1, bw1, , fN, ampN, bwN],
 [t1, f0, amp0, bw0, f1, amp1, bw1, , fN, ampN, bwN],
 ...
]

Where (f0, amp0, bw0) represent the freq, amplitude and bandwidth of partial 0 at a given time, (f1, amp1, bw0) the corresponding data for partial 1, etc.

If interleave is False, it returns three arrays: freqs, amps, bws of the form:

    [[f0, f1, f2, ..., fn]  # at times[0]
     [f0, f1, f2, ..., fn]  # at times[1]
    ]

Note

phase information is not sampled

Args

  • partials (list[np.ndarray]): a list of 2D-arrays, each representing a partial
  • dt (float): sampling period (default: 0.002)
  • t0 (float): start time, or None to use the start time of the spectrum (default: -1)
  • t1 (float): end time, or None to use the end time of the spectrum (default: -1)
  • maxactive (int): limit the number of active partials to this number. If the number of active streams (partials with non-zero amplitude) is higher than maxactive, the softest partials will be zeroed. During resynthesis, zeroed partials are skipped. This strategy is followed to allow to pack all partials at the cost of having a great amount of streams, and limit the streams (for better performance) at the synthesis stage. (default: 0)
  • interleave (bool): if True, all columns of each partial are interleaved (see below) (default: True)

Returns

    (np.ndarray | tuple[np.ndarray, np.ndarray, np.ndarray]) if interleave is True, returns a big matrix where all partials are interleaved and present at all times. Otherwise returns three arrays, (freqs, amps, bws) where freqs represents the frequencies of all partials, etc. See below


partials_save_matrix

def partials_save_matrix(partials: list[np.ndarray], outfile: str =, 
                         dt: float = None, gapfactor: float = 3.0, 
                         maxtracks: int = 0, maxactive: int = 0
                         ) -> tuple[list[np.ndarray], np.ndarray]

Packs short partials into longer partials and saves the result as a matrix

Example

import loristrck as lt
partials, labels = lt.read_sdif(sdiffile)
selected, rest = lt.util.select(partials, minbps=2, mindur=0.005, minamp=-80)
lt.util.partials_save_matrix(selected, 0.002, "packed.mtx")

Args

  • partials (list[np.ndarray]): a list of numpy 2D-arrays, each representing a partial
  • outfile (str): path to save the sampled partials. Supported formats: .mtx, .npy (See matrix_save for more information). If not given, the matrix is not saved (default: ``)
  • dt (float): sampling period to sample the packed partials. If not given, it will be estimated with sensible defaults. To have more control over this stage, you can call estimate_sampling_interval yourself. At the cost of oversampling, a good value can be ksmps/sr, which results in 64/44100 = 0.0014 secs for typical values (default: None)
  • gapfactor (float): partials are packed with a gap = dt * gapfactor. It should be at least 2. A gap is a minimal amount of silence between the partials to allow for a fade out and fade in (default: 3.0)
  • maxtracks (int): Partials are packed in tracks and represented as a 2D matrix where each track is a row. If filesize and save/load time are a concern, a max. value for the amount of tracks can be given here, with the consequence that partials might be left out if there are no available tracks to pack them into. See also maxactive (default: 0)
  • maxactive (int): Partials are packed in simultaneous tracks, which correspond to an oscillator bank for resynthesis. If maxactive is given, a max. of maxactive is allowed, and the softer partials are zeroed to signal that they can be skipped during resynthesis. (default: 0)

Returns

    (tuple[list[np.ndarray], np.ndarray]) a tuple (packed spectrum, matrix)


partials_stretch

def partials_stretch(partials: list[np.ndarray], factor: float, 
                     inplace: bool = False) -> list[np.ndarray]

Stretch the partials in time by a given constant factor

Args

  • partials (list[np.ndarray]): a list of partials
  • factor (float): float. a factor to multiply all times by
  • inplace (bool): modify partials in place (default: False)

Returns

    (list[np.ndarray]) the stretched partials


partials_timerange

def partials_timerange(partials: list[np.ndarray]) -> tuple[float, float]

Return the timerange of the partials: (begin, end)

Args

  • partials (list[np.ndarray]): the partials to query

Returns

    (tuple[float, float]) with the corresponding times in seconds


partials_transpose

def partials_transpose(partials: list[np.ndarray], interval: float, 
                       inplace: bool = False) -> list[np.ndarray]

Transpose the partials by a given interval

Args

  • partials (list[np.ndarray]): the partials to transpose
  • interval (float): the interval in semitones
  • inplace (bool): if True, the partials are modified in place. Otherwise a new partial list is returned (default: False)

Returns

    (list[np.ndarray]) the modified partial list, or the original list modified in place


plot_partials

def plot_partials(partials: list[np.ndarray], downsample: int = 1, 
                  cmap: str = inferno, exp: float = 1.0, linewidth: int = 1, 
                  ax=None, avg: bool = True) -> Any

Plot the partials using matplotlib

Args

  • partials (list[np.ndarray]): a list of numpy arrays, each representing a partial
  • downsample (int): If > 1, only one every downsample breakpoints will be taken into account. (default: 1)
  • cmap (str): a string defining the colormap used (see https://matplotlib.org/users/colormaps.html) (default: inferno)
  • exp (float): an exponential to apply to the amplitudes before plotting (default: 1.0)
  • linewidth (int): the line width of the plot (default: 1)
  • ax: A matplotlib axes. If one is passed, plotting will be done to this axes. Otherwise a new axes is created (default: None)
  • avg (bool): if True, the colour of a segment depends on the average between the amplitude at the start breakpoint and the end breakpoint of the segment Otherwise only the amplitude of the start breakpoint is used (default: True)

Returns

    a matplotlib axes


select

def select(partials: list[np.ndarray], mindur: float = 0.0, minamp: int = -120, 
           maxfreq: int = 24000, minfreq: int = 0, minbps: int = 1, 
           t0: float = 0.0, t1: float = 0.0
           ) -> tuple[list[np.ndarray], list[np.ndarray]]

Selects a seq. of partials matching the given conditions

Select only those partials which have

  • a min. duration of at least mindur AND
  • an avg. amplitude of at least minamp AND
  • a freq. between minfreq and maxfreq AND
  • have at least minbps breakpoints

Example

import loristrck as lt
partials = lt.read_sdif(...)
selected, _ = lt.util.select(partials, minbps=2, mindur=0.005, 
                             minamp=-80, maxfreq=17000)

Args

  • partials (list[np.ndarray]): a list of numpy 2D arrays, each array representing a partial
  • mindur (float): min. duration (in seconds) (default: 0.0)
  • minamp (int): min. amplitude (in dB) (default: -120)
  • maxfreq (int): max. frequency (default: 24000)
  • minfreq (int): min. frequency (default: 0)
  • minbps (int): min. breakpoints (default: 1)
  • t0 (float): only partials defined after t0 (default: 0.0)
  • t1 (float): only partials defined before t1 (default: 0.0)

Returns

    (tuple[list[np.ndarray], list[np.ndarray]]) (selected partials, discarded partials)


sndread

def sndread(path: str, contiguous: bool = True) -> tuple[np.ndarray, int]

Read a sound file.

Args

  • path (str): The path to the soundfile
  • contiguous (bool): If True, it is ensured that the returned array is contiguous. This should be set to True if the samples are to be passed to analyze, which expects a contiguous array (default: True)

Returns

    (tuple[np.ndarray, int]) a tuple (samples:np.ndarray, sr:int)


sndreadmono

def sndreadmono(path: str, chan: int = 0, contiguous: bool = True
                ) -> tuple[np.ndarray, int]

Read a sound file as mono.

If the soundfile is multichannel, the indicated channel chan is returned.

Args

  • path (str): The path to the soundfile
  • chan (int): The channel to return if the file is multichannel (default: 0)
  • contiguous (bool): If True, it is ensured that the returned array is contiguous. This should be set to True if the samples are to be passed to analyze, which expects a contiguous array (default: True)

Returns

    (tuple[np.ndarray, int]) a tuple (samples:np.ndarray, sr:int)


sndwrite

def sndwrite(samples: np.ndarray, sr: int, path: str, encoding: str = None
             ) -> None

Write the samples to a soundfile

Args

  • samples (np.ndarray): the samples to write
  • sr (int): samplerate
  • path (str): the outfile to write the samples to (the extension will determine the format)
  • encoding (str): the encoding of the samples. If None, a default is used, according to the extension of the outfile given. Otherwise, a string 'floatXX' or 'pcmXX' is expected, where XX represent the bits per sample (15, 24, 32, 64 for pcm, 32 or 64 for float). Not all encodings are supported by all formats. (default: None)

wavwrite

def wavwrite(outfile: str, samples: np.ndarray, sr: int = 44100, bits: int = 32
             ) -> None

Write samples to a wav-file (see also sndwrite) as float32 or float64

Args

  • outfile (str): the path of the output file
  • samples (np.ndarray): the samples to write
  • sr (int): the sample rate (default: 44100)
  • bits (int): the bit-width used when writing the samples (default: 32)

write_sdif

def write_sdif(partials: list[np.ndarray], outfile: str, labels=None, 
               fmt: str = RBEP, fadetime: float = 0.0) -> None

Write a list of partials as SDIF.

Note

The 1TRC format forces resampling, since all breakpoints within a 1TRC frame need to share the same timestamp. In the RBEP format a breakpoint has a time offset to the frame time stamp

Args

  • partials (list[np.ndarray]): a seq. of 2D arrays with columns [time freq amp phase bw]
  • outfile (str): the path of the sdif file
  • labels: a seq. of integer labels, or None to skip saving labels (default: None)
  • fmt (str): one of "RBEP" / "1TRC" (default: RBEP)
  • fadetime (float): (default: 0.0)