NAME
Math::SegmentedEnvelope - create/manage/evaluate segmented (curved) envelope
SYNOPSIS
my
$e
= Math::SegmentedEnvelope->new;
# creates random envelope with total duration = 1
$e
->segments;
# number of segments
$e
->levels(
map
$_
* 3,
$e
->levels);
# alter levels
$e
->durs(
map
$_
* (
rand
(0.5) + 0.5),
$e
->durs);
# alter segments durations
$e
->curves(
map
$_
+ 1,
$e
->curves);
# alter curves
$e
->level(
# alter start level of first segment and set it value to end level of last segment
$self
->segments,
$e
->level(0,
$self
->level(0) - 1)
);
$e
->curve(0, 3);
# set curvative for first segment
$e
->dur(0, 0.2);
# set duration of first segment, so overall duration will changed
$e
->duration;
# get it
$e
->normalize_duration;
# scale segment durs so envelope duration will be 1
or
my
$e
= Math::SegmentedEnvelope->new(
# creates custom adsr envelope
# def =>
[
[0,1,0.8,0.7,0],
# levels
[0.1,0.2,0.4,0.3],
# segement duration
[1,2,1,-3]
# segment curvative, 0 for flat, 1 for linear and other for curved
],
is_morph
=> 1,
# default is 0, smooth envelope with default value morpher inside segment
# morpher => sub { ... } # provide custom morpher which will recieve values from 0 to 1, and should return values from 0 to 1 for non-breaking envelope
is_hold
=> 0,
# default is 0, will return boundary levels for positions out of envelope duration
is_fold_over
=> 1,
# default is 0, will fold envelope instead of wraping for positions out of envelope duration
is_wrap_neg
=> 1,
# default is 0, will wrap envelope insted of fold for negative positions
);
$e
->at(
rand
);
# outputs value at random position
$e
->table(1024);
# returns list of values(lookup table) for current envelope with specified size
my
$s
=
$e
->static;
# creates static evaluator with current envelope parameters (coderef)
$s
->(
rand
);
# outputs value at random position, but ~ 50% faster
DESCRIPTION
This module gives abstraction of segmeneted envelope. You can create, modify and make static evaluators, which is faster than object method C<at> calling.
METHODS
- new($definiton, %params)
-
$definition
is a 3 element arrayref of arrayrefs - [[
@levels
], [
@durations
], [
@curves
]]
%params
can provide additional params such C<is_hold>,C<is_morph>,C<morpher>,C<is_fold_over>,C<is_wrap_neg>
if
nothing specified, than random normalized envelope will be created
- at($pos)
-
get value at specified position, position can be out of envelope duration, so it will hold or wrap or fold according configuration [arameters C<is_hold>, C<is_fold_over> and C<is_wrap_neg>
- static
-
returns static evaluator (i.e. coderef)
with
current envelope object settings
- table($size)
-
returns lookup table (i.e. list of
values
) of specified size(
default
= 1024) which represents current form of the envelope
- is_morph(0|1)
-
get/set flag which turns on value morphing inside segment
before
applying curving and scaling.
default
= 0
- morpher(sub {...})
-
get/set morpher,
default
morpher is a C<
sub
{
sin
(PI/2
*$_
[0]) }> which smoothes envelope, morpher recieves value from 0 to 1 and should also
has
same output range
- is_hold(0|1)
-
when
this flag is turned on than C<at> method and static evaluator
with
out-of-duration argument will
return
boundary levels.
default
= 0
- is_fold_over(0|1)
-
when
this flag is turned on and C<is_hold> is turned off than C<at> argument greater than envelope duration will be folded
around
envelope duration insted of wraping.
default
= 0
- is_wrap_neg(0|1)
-
when
this flag is turned on and C<is_hold> is turned off than C<at> argument < 0 will be wraped
around
envelope insted of folding.
default
= 0
- segments
-
returns number of segments
- duration
-
returns total envelope duration
- normalize_duration
-
scale segment durations, so total duration becomes 1
- def
-
returns current envelope definition (see L<new> method)
- levels(@new_levels)
-
get/set envelope levels,
if
setting than provided list must have equal
length
to levels specified in initial definition (i.e. C<segments + 1>)
- level($pos, [$level])
-
get/set level at position
- durs([@new_durs])
-
same as C<levels>, but get/sets durations
for
segments
- dur($pos, [$level])
-
get/set dur at position
- curves([@new_curves])
-
same as durs, but
for
curves
- curve($pos, [$level])
-
get/set curvative at position
EXAMPLES
- Plot
-
my
$e
= Math::SegmentedEnvelope->new(
is_morph
=> 1);
my
$t
=
$e
->table(4096);
line_plot(
$t
);
- Interpolate
-
use
PDL;
interpolate(
rand
(4095), sequence(4096), pdl(
$t
));
# interpolate at random position
- Animation
-
my
$e
= Math::SegmentedEnvelope->new(
is_morph
=> 1);
my
$v
= 0;
# some property
my
$w
= AE::timer(0, 1/60,
sub
{
# refresh $v with 60Hz rate
state
$s
=
$e
->static;
# get static evaluator
state
$started
= AE::now;
$v
=
$s
->(AE::now -
$started
);
# or $e->at(..) if $e can be altered somewhere
});
my
$k
= AE::timer(10, 0,
sub
{
undef
$w
});
# kill previous timer after 10secs
my
$i
= AE::idle(
sub
{ ... });
# animate $v using OpenGL, SDL and etc..
AE::cv->
recv
;
- visual representation of arbitrary definition
-
Math::SegmentedEnvelope->new([[0,1,0.5,0],[0.5,0.5,1],[-3,1/3,4]],
is_morph
=> 1)
SUPPORT
GitHub
Search MetaCPAN
ACKNOWLEDGEMENTS
AUTHOR
Yegor Korablev <egor@cpan.org>
LICENSE
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
SEE ALSO
PDL, OpenGL, SDL, AnyEvent, Math::Fractal::Noisemaker
TODO
blending,stacking,duration scaling,delaying and some common predefined envelopes more docs,tests and examples
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 178:
'=item' outside of any '=over'