NAME

Peta::Synth::Analysis - measuring sound: a note's partials, its level and brightness over time

VERSION

version 0.2610180

SYNOPSIS

use Peta::Synth::Analysis;
my $wav = Peta::Synth::Analysis::read_wav('note.wav');
my $x = Peta::Synth::Analysis::mono(@{ $wav->{channels} });
my $p = Peta::Synth::Analysis::partials($x, rate => $wav->{rate}, f0 => 261.6, count => 16);
my ($B, $f) = Peta::Synth::Analysis::stretch(map { $_ && $_->[0] } @{ $p->{freq} });

DESCRIPTION

What bin/peta-analyze measures with: the tools to compare an instrument of this synthesizer with a recording, or with itself after a change. Sound is an array of samples (full scale 1) at a rate. Levels are in dB of amplitude: a sine of amplitude 1 is 0 dB as a partial; RMS levels are the samples' (that sine is -3 dB).

FUNCTIONS

read_wav

read_wav($file): { rate, channels => [ \@samples, ... ] }; PCM of 8, 16, 24 or 32 bits, floats of 32 or 64.

mono

mono(@channels): their mean.

spectrum

spectrum(\@x, $rate, $at, $size, $pad = 4): the magnitudes of $size samples from $at under a Hann window, zero-padded $pad times (a sine of amplitude A peaks at A), and the Hz of a bin.

peak

peak(\@magnitudes, $bin, $low, $high): the strongest peak between two frequencies, its frequency and amplitude interpolated between the bins.

partials

partials(\@x, rate => ..., f0 => ..., count => 16, size => 4096, times => [...]): each partial of a note at each time (seconds into the sound), found where the partials below it say it is, so that a stiff string's are followed. { times, freq => [k][t], level => [k][t] }, k from 1, levels in dB.

stretch

stretch(@freq) (indexed by k, from 1): the stiffness B and fundamental f of f_k = k f sqrt(1 + B k^2) that fit them best.

slope

slope(\@times, \@levels): dB a second, by least squares.

envelope

envelope(\@x, $rate, $step = 0.05): the RMS level of every step seconds.

centroid

centroid(\@x, $rate, $at, $size = 4096): the spectral centroid (Hz) of a frame.

bands

bands(\@x, $rate, from => 0, to => ..., per => 1, size => 4096): the spectrum's power in bands (per an octave, centred on 1 kHz's octaves), averaged over frames from and to (seconds). [ { centre, level } ].

wobble

wobble(\@x, $rate, $from, $to): how much the level moves (tremolo, beating): the RMS (dB) of the level every 10 ms about its straight line, and how often it goes up and down (Hz).

vibrato

vibrato(\@x, $rate, $f0, $from, $to): how much the pitch moves: the RMS in cents of the strongest of the first four partials, every 20 ms.

noise

noise(\@x, $rate, $f0, $at, $size = 4096): how much of a frame is not the note's partials, in dB of the whole.

response

response([ [\@x, $rate, $f0], ... ], count => 16, times => [0.5, 1], slope => 1, per => 3): what a body does to the harmonics of a source falling as k^-slope, from notes across a range: the partials' levels less the source's fall, each note's whole level taken out, averaged in bands by frequency. [ { centre, level, count }, ... ], the loudest band 0 dB.

AUTHOR

PetaMem s.r.o. <info@petamem.com>

COPYRIGHT

Copyright (c) 2026 PetaMem s.r.o.

LICENSE

This package is free software, dual-licensed under the Artistic License 2.0 and the BSD 2-Clause License. See the LICENSE file of the distribution.