Skip to main content

buf2ptracks

buf2ptracks(
@buffer ? ## llll (required)
@winstartfromzero 0
@framesize 2048
@hopsize 512
@freqdevoffset 20
@freqdevslope 0.01
@magnitudethreshold 2e-4
@maxfrequency 22050
@minfrequency 0
@maxpeaks 100
@maxnsines 100
@numframes 'auto'
@orderby 'frequency'
@overlap 4
@wintype 'hann'
@ampunit 0
@antimeunit 1
@angleunit 0
@frequnit 0
@timeunit 0
@downmix 1
) -> llll

Converts a buffer into partial tracks via analysis, consisting of a llll with the keys frequencies, magnitudes, and phases, structured as follows:

[
[ 'frequencies'
[ ## buffer channel 1
[ <fq_1> <fq_2> ... <fq_N> ] ## frame 1
...
[ <fq_1> <fq_2> ... <fq_N> ] ## frame N
]
...
[ ## buffer channel N
...
]
]
[ 'magnitudes'
[ ## buffer channel 1
[ <mag_1> <mag_2> ... <mag_N> ] ## frame 1
...
[ <mag_1> <mag_2> ... <mag_N> ] ## frame N
]
...
[ ## buffer channel N
...
]
]
[ 'phases'
[ ## buffer channel 1
[ <phase_1> <phase_2> ... <phase_N> ] ## frame 1
...
[ <phase_1> <phase_2> ... <phase_N> ] ## frame N
]
...
[ ## buffer channel N
...
]
]
]
warning

buf2ptracks is computationally expensive and can take a long time.


Arguments

  • @buffer ? [llll]: buffer to analyze. (required)
  • @winstartfromzero [int]: first window starts at zero (default: 0).
    • 0: off
    • 1: on
  • @framesize [int]: window size, in samples. (default: 2048).
  • @hopsize [int]: hop size, in samples. (default: 512).
  • @freqdevoffset [int]: frequency deviation offset. (default: 20).
  • @freqdevslope [int/float]: frequency deviation slope. (default: 0.01).
  • @magnitudethreshold [float]: peak amplitude threshold. (default: 2e-4).
  • @maxfrequency [int/float]: max. frequency of the range to evaluate. (default: 22050).
  • @minfrequency [int/float]: min. frequency of the range to evaluate. (default: 0).
  • @maxpeaks [int]: max. number of returned peaks. (default: 100).
  • @maxnsines [int]: max. number of sines per frame. (default: 100).
  • @numframes [int/symbol]: number of frames. (default: 'auto').
  • @orderby [symbol]: ordering feature. (default: 'frequency').
    • 'frequency'
    • 'magnitude'
  • @overlap [int]: overlap. (default: 4).
  • @wintype [symbol]: window type. (default: 'hann').
    • 'rectangular'
    • 'triangular'
    • 'sine'
    • 'hann'
    • 'hamming'
    • 'blackman'
    • 'nuttall'
    • 'blackmannuttall'
    • 'blackmanharris'
    • 'gaussian'
    • 'sqrthann'
    • 'sqrthamming'
  • @ampunit [int]: amplitude unit. (default: 0).
    • 0: linear
    • 1: decibels
  • @antimeunit [int]: analysis time unit. (default: 1).
    • 0: milliseconds
    • 1: samples
    • 2: duration ratio
    • 3: milliseconds difference
    • 4: samples difference
  • @angleunit [int]: angle unit. (default: 0).
    • 0: radians
    • 1: degrees
    • 2: turns
  • @frequnit [int]: unit for frequency components in @func. (default: 0).
    • 0: Hertz
    • 1: BPM
    • 2: midicents
    • 3: MIDI
  • @timeunit [int]: time unit. (default: 0).
    • 0: milliseconds
    • 1: samples
    • 2: duration ratio
    • 3: milliseconds difference
    • 4: samples difference
  • @downmix [int]: downmix buffer. (default: 1).
    • 0: off
    • 1: on

Output

partial track analysis [llll]


Usage

$buffer = importaudio('poem.wav').setkey('duration', 1500); ## input buffer
$sr = $buffer.getkey('sr'); ## get sampling rate
$hopsize = 512; ## set hop size
$ptracks = $buffer.buf2ptracks(@magnitudethreshold 0.01 @hopsize $hopsize); ## extract partial tracks
## unpack frequency, magnitude, and phase tracks
$freqs = $ptracks.getkey('frequencies');
$mags = $ptracks.getkey('magnitudes');
$phases = $ptracks.getkey('phases');

$stretch = 8; ## define stretching amount
## compute ms frame duration based on hop size and sampling rate
$framedur = ($hopsize / $sr) * 1000.;
## parallel iteration through every numeric value
for $fq $addr in $freqs, $mag in $mags, $ph in $phases with @maxdepth -1 do (
## skip invalid frequencies
if $fq > 0 then (
$frame = $addr:-2; ## frame id from address
$onset = $frame * $framedur; ## frame onset time
$grain = cycle( ## sine grain
@frequency $fq
@phase $ph
@duration $framedur * $stretch * 4 ## overlap of 4
);
$env = [0 0 0] [0.5 $mag * 0.25 -0.25] [1 0 0.25]; ## grain envelope
$grain.transcribe(
@onset $onset * $stretch ## apply time stretching
@gain $env
@pan rand()
)
)
);
render(@play 1)