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
: off1
: 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
: linear1
: decibels
@antimeunit
[int]: analysis time unit. (default:1
).0
: milliseconds1
: samples2
: duration ratio3
: milliseconds difference4
: samples difference
@angleunit
[int]: angle unit. (default:0
).0
: radians1
: degrees2
: turns
@frequnit
[int]: unit for frequency components in@func
. (default:0
).0
: Hertz1
: BPM2
: midicents3
: MIDI
@timeunit
[int]: time unit. (default:0
).0
: milliseconds1
: samples2
: duration ratio3
: milliseconds difference4
: samples difference
@downmix
[int]: downmix buffer. (default:1
).0
: off1
: 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)