Você está na página 1de 277

AVISYNTH Documentation

Table of Contents
AVISYNTH Documentation.............................1 ArraySumProduct...........................28
Packages main index......................................8 The array :: operators module.............29
Introduction....................................................8 Required modules...........................29
AVSLib Packages...........................................8 Functions........................................29
The array package...........................................9 Constants........................................29
Required packages.....................................9 Variables.........................................29
Modules.....................................................9 ArrayOpArray................................30
The array :: core module.....................10 ArrayOpArrayFunc........................31
Required modules...........................10 ArrayOpFunc..................................32
Functions........................................10 ArrayOpValue.................................33
Constants........................................11 ArraySum.......................................34
Variables..............................................11 The array :: powseries module............35
ArrayCreate....................................12 Required modules...........................35
ArrayDelete....................................12 Functions........................................35
ArrayDelimiterGet..........................13 Constants........................................35
ArrayDelimiterReset......................13 Variables.........................................35
ArrayDelimiterSet..........................14 ArrayPowSeries..............................36
ArrayFill.........................................14 ArrayPowSeriesA...........................36
ArrayGet.........................................15 ArrayPowSeriesAA........................36
ArrayGetString...............................15 PowSeriesA....................................37
ArrayGetValueRegisterNewHandler PowSeriesAA.................................38
........................................................16 The array :: properties module............39
ArrayGetValueResetDefaultHandler Required modules...........................39
........................................................16 Functions........................................39
ArrayInsert......................................17 Constants........................................39
ArrayLen........................................17 Variables.........................................39
ArrayRange....................................18 ArrayContains................................40
ArraySet..........................................19 ArrayElmCount..............................40
ArraySetValueRegisterNewHandler ArrayIndexOf.................................41
........................................................19 ArrayMax.......................................41
ArraySetValueResetDefaultHandler ArrayMin........................................42
........................................................20 The array :: slices module...................43
The array :: functions module.............21 Required modules...........................43
Required modules...........................21 Functions........................................43
Functions........................................21 Constants........................................43
Constants........................................21 Variables.........................................43
Variables.........................................21 ArrayDelRange...............................44
ArrayAverage.................................22 ArrayDeplex...................................45
ArrayClamp....................................22 ArrayGetRange...............................46
ArrayEqual.....................................22 ArrayInsRange................................46
ArrayGreater...................................23 ArrayJoin........................................47
ArrayGreaterOrEqual.....................23 ArrayPlex........................................48
ArrayLess.......................................24 ArraySetRange...............................49
ArrayLessOrEqual..........................24 ArraySplit.......................................50
ArrayNegate...................................25 The array :: transforms module...........51
ArrayNot.........................................25 Required modules...........................51
ArrayNotEqual...............................26 Functions........................................51
ArrayProduct..................................26 Constants........................................51
ArraySpline....................................27 Variables.........................................51
ArrayStDev.....................................27 ArrayDistinct..................................52
ArrayElmSwap...............................52 And.................................................74
ArrayInvert.....................................53 And2...............................................74
ArrayReduce...................................53 Not..................................................75
ArrayRotate....................................54 Or....................................................75
ArraySort........................................55 Or2..................................................76
The base package..........................................56 Xor2................................................76
Required packages...................................56 The clip package...........................................77
Modules...................................................56 Required packages...................................77
The base :: constants module..............57 Modules...................................................77
Required modules...........................57 The clip :: arrays module.....................78
Functions........................................57 Required modules...........................78
Constants........................................57 Functions........................................78
Variables.........................................58 Constants........................................78
The base :: conversion module............59 Variables.........................................78
Required modules...........................59 JointFPS..........................................79
Functions........................................59 JointPixelType................................80
Constants........................................59 The clip :: core module.......................81
Variables.........................................59 Required modules...........................81
CBool..............................................60 Functions........................................81
CClip..............................................61 Constants........................................81
CFloat.............................................62 Variables.........................................81
CInt.................................................63 ColorSpace.....................................82
CString............................................64 IsPixelType.....................................82
The base :: core module......................65 MakeRGBColor..............................82
Required modules...........................65 SafeHeight......................................83
Functions........................................65 SafeWidth.......................................83
Constants........................................65 SplitRGBColor...............................84
Variables.........................................65 The debug package.......................................85
ImportIf..........................................66 Required packages...................................85
IsCallable........................................66 Modules...................................................85
Null.................................................67 The debug :: core module....................86
Self..................................................67 Required modules...........................86
Throw.............................................67 Functions........................................86
Typename.......................................68 Constants........................................86
Undef..............................................68 Variables.........................................86
VarType...........................................69 ArrayPrint.......................................87
The base :: version module.................70 ArrayPrintCP..................................87
Required modules...........................70 Break..............................................88
Functions........................................70 BreakIf............................................88
Constants........................................70 Print................................................89
Variables.........................................70 The debug :: logging module..............90
AvslibVersion.................................71 Required modules...........................90
AvslibVersionNumber....................71 Functions........................................90
AvslibVersionString........................71 Constants........................................91
The bool package..........................................72 Variables.........................................91
Required packages...................................72 DebugLog.......................................92
Modules...................................................72 GetDebugFile.................................92
The bool :: core module......................73 GetDebugMode..............................93
Required modules...........................73 SetDebugFile..................................93
Functions........................................73 SetDebugMode...............................93
Constants........................................73 The numeric package....................................94
Variables.........................................73 Required packages...................................94
Modules...................................................94 ExpBs............................................111
The numeric :: core module................95 Log10............................................111
Required modules...........................95 LogBs............................................111
Functions........................................95 Sinh...............................................112
Constants........................................95 Tan................................................112
Variables.........................................95 The numeric :: powseries module.....113
Clamp.............................................96 Required modules.........................113
Count..............................................96 Functions......................................113
DegToRad ......................................96 Constants......................................113
Dif2.................................................97 Variables.......................................113
Div2................................................97 Factorial........................................114
IsEven.............................................97 Polynomial....................................114
IsOdd..............................................98 PowSeries.....................................115
Max.................................................98 The numeric :: rounding module.......117
Max2...............................................98 Required modules.........................117
Min.................................................99 Functions......................................117
Min2...............................................99 Constants......................................117
Mod2..............................................99 Variables.......................................117
Product..........................................100 CeilBs...........................................118
Product2........................................100 FloorBs.........................................118
RadToDeg.....................................100 FRound.........................................119
Sum...............................................101 IntBs..............................................119
Sum2.............................................101 RoundBs.......................................120
The numeric :: curves2d module.......102 RoundEven...................................120
Required modules.........................102 RoundOdd....................................121
Functions......................................102 The numeric :: statistics module.......122
Constants......................................102 Required modules.........................122
Variables.......................................102 Functions......................................122
Circle............................................103 Constants......................................122
Ellipsis..........................................103 Variables.......................................122
Hyperbola.....................................104 Average.........................................123
Line...............................................104 StDev............................................123
Line1pt..........................................105 SumSquare....................................123
Line2pt..........................................105 The string package......................................124
Parabola........................................105 Required packages.................................124
The numeric :: functions module......106 Modules.................................................124
Required modules.........................106 The string :: core module..................125
Functions......................................106 Required modules.........................125
Constants......................................106 Functions......................................125
Variables.......................................106 Constants......................................125
ArcCos..........................................107 Variables.......................................125
ArcCosh........................................107 IsQuoted.......................................126
ArcCot..........................................107 QuoteNoexpr................................126
ArcCot..........................................108 StrCompare...................................127
ArcSin...........................................108 StrFill............................................127
ArcSinh.........................................108 StrLeft...........................................128
ArcTan..........................................109 StrMid...........................................128
ArcTanh........................................109 StrQuote........................................129
Cosh..............................................109 StrRight........................................129
Cot................................................110 StrUnquote....................................130
Coth..............................................110 ZStrip............................................130
Exp10............................................110 The string :: search module...............131
Required modules.........................131 EditDelete.....................................156
Functions......................................131 EditInsert......................................157
Constants......................................131 EditJoin.........................................158
Variables.......................................131 EditReplace..................................159
StrFind..........................................132 EditTrim.......................................161
StrReplace....................................133 The filters :: frames module..............163
The string :: sprintf module...............134 Required modules.........................163
Required modules.........................134 Functions......................................163
Functions......................................134 Constants......................................163
Constants......................................134 Variables.......................................163
Variables.......................................134 FrameFilter...................................164
StrPrint..........................................135 FrameFilterReader........................166
The filters package......................................137 The filters :: multiedit module...........168
Required packages.................................137 Required modules.........................168
Modules.................................................137 Functions......................................168
The filters :: animate module............138 Constants......................................168
Required modules.........................138 Variables.......................................168
Functions......................................138 EditTrimRange.............................169
Constants......................................138 The filters :: resize module................170
Variables.......................................138 Required modules.........................170
LineAnim......................................139 Functions......................................170
PolygonAnim................................141 Constants......................................170
MoveOverlay................................144 Variables.......................................170
ResizeOverlay..............................146 GetDefaultResizer........................171
The filters :: channels module...........147 Resize...........................................172
Required modules.........................147 ResizeToFit...................................173
Functions......................................147 ResizeToTarget.............................174
Constants......................................147 SetDefaultResizer.........................175
Variables.......................................147 The filters :: stack module.................176
ChannelIndex................................148 Required modules.........................176
IsRGB24Channels........................148 Functions......................................176
IsRGB32Channels........................148 Constants......................................176
IsRGBChannels............................149 Variables.......................................176
IsYUVChannels............................149 Stack.............................................177
IsYUY2Channels..........................149 StackToFit.....................................178
IsYV12Channels..........................150 The filters :: utility module...............179
MergeARGB.................................150 Required modules.........................179
MergeRGB...................................150 Functions......................................179
MergeVideoChannels...................151 Constants......................................179
MergeYUV...................................151 Variables.......................................179
ShowBlue.....................................152 ConvertToTarget...........................180
ShowGreen...................................152 FilterChain....................................180
ShowRed......................................152 FilterVarChain..............................181
ShowU..........................................153 ScaleToPC....................................181
ShowV..........................................153 ScaleToTV....................................182
ShowY..........................................154 Installation Instructions..............................183
SplitVideoChannels......................154 Downloading the right version of AVSLib
The filters :: edit module...................155 ...............................................................183
Required modules.........................155 Installing AVSLib...................................183
Functions......................................155 Standard (recommended) installation
Constants...........................................155 procedure...........................................183
Variables.......................................155 Manual installation procedure...........183
Using AVSLib........................................183 8. I made a script using arrays but I
Solving installation problems................184 always get a "__left_str: string has >
Uninstalling AVSLib...................................184 1024 chars" message when I try to run
Standard (recommended) installation it. What's going wrong?.....................188
procedure...............................................184 9. I try to use the EditJoin filter with a
Manual installation procedure...............184 custom join function but I get an
FAQs...........................................................185 "invalid arguments to function..." error?
General questions...................................185 What's going wrong?.........................188
1. What is AVSLib?...........................185 Support...................................................189
2. What makes AVSLib different from 1. I want to submit a bug report. What
other plugins I have found for Avisynth? should I do?.......................................189
...........................................................185 2. I want a feature not included in
3. What are the licencing terms of AVSLib. How can I request it?.........189
AVSLib?............................................185 3. Where can I find support about using
4. Where can I download the latest AVSLib?............................................189
version of AVSLib?...........................185 4. I have a question about AVSLib.
5. Where can I find documentation for Where do I seek for an answer?........189
AVSLib?............................................185 5. Where can I contact the developers of
6. What are the plans for the future?. 185 AVSLib?............................................189
Installation.............................................186 Contribution...........................................190
1. How do I install AVSLib?.............186 1. I want to participate on AVSLib
2. How do I install multiple versions of development. How can I do this?......190
AVSLib?............................................186 2. I want to contribute texts or script
3. I want a partial install of AVSLib, examples to AVSLib documentation.
how can it be accomplished?.............186 How can I do this?.............................190
4. How do I know what version of Structure of the AVSLib library..................191
AVSLib I have installed in my system? Library Structure....................................191
...........................................................186 Library Specifications.......................191
5. How do I uninstall AVSLib?.........186 Naming conventions..........................192
Usage.....................................................187 Reserved names.................................192
1. Are there any limitations in AVSLib? Reserved actions................................192
...........................................................187 Examples....................................................193
2. Will these limitations be removed in a 1. Stack clips in a matrix........................193
future version of AVSLib?................187 Apply a swap transition.........................196
3. Are there any recommendations 3. Create a simple movie intro clip........198
regarding the use of AVSLib features? 4. Make a palette clip with all Avisynth
...........................................................187 named colors..........................................199
4. I try to run a script containing calls to 5. Load a text file with arbitrary clips....202
AVSLib functions and I get the "I don't 6. Create an enhanced movie intro clip..204
know what xxx means" error from 7. Stack clip frames in a matrix.............206
Avisynth. What's going wrong?........187 8. Load, convert and join arbitrary clips
5. I get unexpected errors pointing to ...........................................................208
array operator functions 9. Make an animated draw of a curve with
(ArrayOpValue / ArrayOpFunc / random orbits.........................................211
ArrayOpArray / ArrayOpArrayFunc). 10. Loop through filter settings..............221
Didn't you tested them for errors?.....187 11. Loop through filter settings - revisited
6. My animation gets out of the clip ...............................................................223
area. What's going wrong?................188 12. Load, convert and join with transition
7. VirtualDub either crashes or displays effect arbitrary clips...............................226
a "sctip open failed!" messagebox when 13. Multi-color mask creation and
I try to run a script containing AVSLib manipulation..........................................230
commands. What's going wrong?.....188 14. Create an expanding rotating circle of
rotating stars...........................................234 Understanding editing filters.................267
15. Per frame filtering, a position + size + Introduction.......................................267
color animation......................................242 The editing model.............................267
16. Per frame filtering, exporting specific Assembling the parts of the final result
frame(s)..................................................248 ...........................................................269
Tutorials......................................................255 User-supplied functions....................270
Understanding containers......................255 A generic example of a user-supplied
Implementation selections.................255 function.............................................270
Impact of selections on functionality 256 Understanding animation filters.............272
What containers can do for you........258 Introduction.......................................272
Hints for effective use.......................259 Animation coordinate system............272
Container operators................................260 The significance of masks.................272
Introduction.......................................260 Usage tips and examples...................273
Array operators..................................260 Using the loader module to build Avisynth
ArrayOpValue...............................260 script libraries........................................274
ArrayOpFunc................................261 Introduction.......................................274
ArrayOpArray..............................262 Module internals................................274
ArrayOpArrayFunc......................263 Package internals...............................275
ArraySum.....................................264 Library internals................................275
Usage (what to do and what not to do) Library organisation..........................277
...........................................................265
Packages main index

Introduction
AVSlib is organised in an hierarcy of packages and modules that allow script authors to selectively load only the
modules that are needed.
Thus, faster loading times and fewer namespace collisions can be achieved. In addition, the script author does not
need to worry for any modules' dependencies, since each module will load by itself any other modules that it
requires.
This is achieved by the use of the special loader module, toghether with appropriate definitions at the start of each
package and module. See the Using the "loader.avsi" module to build Avisynth script libraries tutorial for more
details.

AVSLib Packages
Name Description
The array package contains modules that implement the array container type and all its associated
array
operations (creation, manipulation, etc.).

The base package contains modules that provide basic extensions to Avisynth script language as
base
well as basic components of other AVSLib modules.

The bool package contains modules that extend standard Avisynth operations on variables of
bool
boolean type.

The clip package contains modules that extend standard Avisynth operations on variables of clip
clip
type.

debug The debug package contains modules that provide debuging facilities for script developers.

The deprecated package contains modules created for backwards compatibility purposes.

The modules provide functions defined in previous AVSLib versions that are now deprecated and
deprecated will be removed some time in the future.

Note that no module of this package is included in the prebuilt library configurations (those that
can be passed to LoadLibrary()) and thus they must be explicitly loaded by the script developer.

The filters package contains modules that implement various useful filters (clip transformation
filters
functions); for example animation, editing, resizing and stacking filters.

The numeric package contains modules that extend standard Avisynth operations on variables of
numeric
numeric type (ints and floats).

The string package contains modules that extend standard Avisynth operations on variables of
string
string type.
The array package
The array package contains modules that implement the array container type and all its associated operations
(creation, manipulation, etc.).

Required packages
The array package requires modules from the following packages (see the specific modules' documentation for
actual dependencies): base, numeric, string.

Modules
Name Description
This module provides functions, constants and global variables for the performance of core
core array operations, such as creating and deleting arrays, getting and setting an array element,
defining action handlers for array values, etc.

This module provides functions, constants and global variables for the performance of
functions
common array operations such as comparisons, negation, product, average, etc.

This module provides functions, constants and global variables for the implementation of
operators
array operators, the core mechanism for performing operations on arrays.

This module provides functions, constants and global variables for the implementation of
powseries
additional power series functions, besides the core one (PowSeries()).

This module provides functions, constants and global variables for getting / setting common
properties
array properties such as whether (or how many times) a value is contained in an array, etc.

This module provides functions, constants and global variables for the implementation of
slices
operations on array slices (ie subranges) such as selection, deletion, replacement, etc.

This module provides functions, constants and global variables for the implementation of
transforms
array transformations such as inversion, sorting, etc.
The array :: core module
The array :: core module provides functions, constants and global variables for the performance of core array
operations, such as creating and deleting arrays, getting and setting an array element, defining action handlers for
array values, etc.

Required modules
base :: core, string :: core

Functions
Name Description
Returns a new array from the supplied arguments, in the order provided.
ArrayCreate()
The function accepts up to 60 arguments...

Deletes an element from the array passed as argument and returns the
ArrayDelete()
resulting array...

ArrayDelimiterGet() Returns the current array elements delimiter...

Assigns the library's default value as the array elements delimiter and
ArrayDelimiterReset()
updates internal library variables. Returns the previous setting...

Assigns a new array elements delimiter and updates internal library


ArrayDelimiterSet()
variables. Returns the previous setting...

Returns an array consisting of a number of copies of a value (each copy


ArrayFill()
can be independently manipulated)...

Retrieves an element from the array, with specified index and returns its
ArrayGet()
value...

ArrayGetString() Retrieves and returns the string representation of an array's element, ...

Assigns a new array value-retrieve handler function for use by array


ArrayGetValueRegisterNewHandler()
routines...

Resets the array value-retrieve handler function to the default AVSLib


ArrayGetValueResetDefaultHandler()
handler...

ArrayInsert() Inserts new_value before array[index] and returns the ...

Returns the length of the array, ie the number of elements stored inside
ArrayLen()
it...

ArrayRange() Returns a subrange of an array...

ArraySet() Assigns a new value to a specified array element...

ArraySetValueRegisterNewHandler() Assigns a new array value-set handler function for use by array routines...

ArraySetValueResetDefaultHandler() Resets the array value-set handler function to the default AVSLib
handler...

Constants
None

Variables
Name Description
ArrayGetValueHandler Holds the name of the handler function for retrieving a value from an array's element.

ArraySetValueHandler Holds the name of the handler function for setting an array element to a new value.
ArrayCreate
Module: array :: core
Definition:
ArrayCreate (val "elm01", val "elm02", val "elm03", val "elm04", ... , val "elm60")

Description:
Returns a new array from the supplied arguments, in the order provided.
The function accepts up to 60 arguments. For arrays with > 60 elements one must use multiple function calls for
60 elements' blocks and join the blocks with the ArrayJoin or ArrayInsRange functions.
Notes and conditions on arguments relations:
If none argument is supplied, the function returns an empty array (ie an array with zero elements).

Examples:
a1 = ArrayCreate(2, 4, 3.5, 4.12, 12.01)
c1 = AviSource( ... )
c2 = AviSource( ... )
c3 = AviSource( ... )
c4 = AviSource( ... )
a2 = ArrayCreate(c1, c1.Levels(0,1,255,0,200), c2, c3, c4, c4.Tweak(hue=10))

ArrayDelete
Module: array :: core
Definition:
ArrayDelete(string array, int "index")

Description:
Deletes an element from the array passed as argument and returns the resulting array.
Arguments: array: The array to operate on.
"index" (Optional, defaults to ArrayLen(array) - 1, ie the last array element): The index of the array element to
delete.
Examples:
ar1 = "2, 3, 5, 7"
ar2 = "true, true, false, true"
ar3 = "This,is,a,dog."
ar1 = ArrayDelete(ar1) # ar1 is now "2, 3, 5"
ar2 = ArrayDelete(ar2, 2) # ar2 is now "true, true, true"
ar3 = ar3.ArrayDelete(2) # ar3 is now "This,is,dog."
ArrayDelimiterGet
Module: array :: core
Definition:
ArrayDelimiterGet()

Description:
Returns the current array elements delimiter.
Examples:
cur_dlm = ArrayDelimiterGet()
# do a custom action based on this value
pos = FindStr(arr, cur_dlm)

ArrayDelimiterReset
Module: array :: core
Definition:
ArrayDelimiterReset()

Description:
Assigns the library's default value as the array elements delimiter and updates the corresponding internal library
variables. Returns the previous setting.
Note that this is a global setting affecting immediately all subsequent operations on arrays.

Examples:
old = ArrayDelimiterReset()
...
# do some action that assumes default settings and
# then restore the old value
...
dummy = ArrayDelimiterSet(old)
# assign to dummy to avoid assigning to last
ArrayDelimiterSet
Module: array :: core
Definition:
ArrayDelimiterSet(string delimiter)

Description:
Assigns delimiter as the new array elements delimiter and updates the corresponding internal library variables.
Returns the previous setting.
Note that this is a global setting affecting immediately all subsequent operations on arrays.

Examples:
old = ArrayDelimiterSet(" | ")
...
# do some action and then restore the old value
...
dummy = ArrayDelimiterSet(old)
# assign to dummy to avoid assigning to last

ArrayFill
Module: array :: core
Definition:
ArrayFill(val base, int count, bool "strict")

Description:
Returns an array consisting of count copies of base (each copy can be independently manipulated).
If count == 0, a null string is returned.
The "strict" optional parameter when set to false makes the function to return a null (zero length) array when a
negative count value is passed (the default behavior is to throw an error).

Examples:
a1 = ArrayFill(1, 5) # a1 == "1,1,1,1,1"
clp = AviSource(...)
a2 = ArrayFill(clp, 4)
# a2 now contains 4 copies of clp, each one independent of clp
a2 = a2.ArraySet(0, a2.ArrayGet(0).Tweak(hue=20))
a2 = a2.ArraySet(3, a2.ArrayGet(0).Tweak(cont=2))
# a2 1st and 4th elements are now different from the others
a3 = ArrayFill(2.35, 0) # a3 == "" (empty array)
# this will halt script with an error
a4 = ArrayFill("abc", -1)
# this will return a null array (same result as a3, above)
a5 = ArrayFill("abc", -1, false)
ArrayGet
Module: array :: core
Definition:
ArrayGet(string array, int index)

Description:
Retrieves an element from the array, with index index and returns its value.
This is the equivalent of the var = array[index] statement used in many programming languages, where valid
indexes are in the range [0..ArrayLen(array)-1].

Examples:
a1 = "0.5, 1.0, 1.5, 2.0, 2.5"
num = ArrayGet(a1, 0) # num == 0.5
c1 = AVISource(...)
a2 = ArrayCreate(c1, c1.Trim(0, -50), c1.Trim(50, -50), c1.Tweak(hue=120))
cl = a2.ArrayGet(1) # get the 2nd element of a2
fc = cl.Framecount # cl is a clip; fc == 50

ArrayGetString
Module: array :: core
Definition:
ArrayGetString(string array, int index)

Description:
Retrieves and returns the string representation of an array's element, as it is stored internally to the array; no
attempt is made to evaluate the element by passing its string representation to Eval().
This function is intended primarily for extension developers.

Examples:
a1 = "0.5,1.0,1.5,2.0,2.5"
s1 = a1.ArrayGetString(0) # s1 == "0.5"
c1 = AVISource(...)
a2 = ArrayCreate(c1, c1.Trim(0, -50), c1.Trim(50, -50), c1.Tweak(hue=120))
s2 = a2.ArrayGetString(1)
# assuming this is the 1st clip array created by the script
# s2 == "__acp__2"
return Eval(s2)
# the script will return the second element of a2, ie c1.Trim(0, -50).
ArrayGetValueRegisterNewHandler
Module: array :: core
Definition:
ArrayGetValueRegisterNewHandler(string new_handler)

Description:
Makes new_handler the new array value-retrieve handler function by assigning it to the ArrayGetValueHandler
global variable.
Returns the previous value of the variable.
The assignment is made only if the passed argument is callable, as decided by the IsCallable() library function.
Note that this is a global setting affecting immediately all subsequent operations on arrays.

Examples:
function my_array_get_handler(...) {...}
...
oldhandler = ArrayGetValueRegisterNewHandler("my_array_get_handler")
# perform your custom array operations here
...
# if afterwards you want the previous behavior, reset the old handler
dummy = ArrayGetValueRegisterNewHandler(oldhandler)

ArrayGetValueResetDefaultHandler
Module: array :: core
Definition:
ArrayGetValueResetDefaultHandler()

Description:
Resets the array value-retrieve handler function to the default AVSLib handler by assigning it to the
ArrayGetValueHandler global variable.
Returns the previous value of the variable.
Note that this is a global setting affecting immediately all subsequent operations on arrays.

Examples:
function my_array_get_handler(...) {...}
...
oldhandler = ArrayGetValueRegisterNewHandler("my_array_get_handler")
# perform your custom array operations here
...
# if afterwards you want the default behavior, reset the handler
dummy = ArrayGetValueResetDefaultHandler()
ArrayInsert
Module: array :: core
Definition:
ArrayInsert(string array, val new_value, int "index")

Description:
Inserts new_value before array[index] and returns the resulting array. ..
As a result the array is expanded, new_value is positioned at array[index] and all subsequent elements's indexes
are increased by one.
If (optional) index is ommited, then new_value is appended to the end of array (same as providing an index with
value equal to array.ArrayLen()).

Examples:
a1 = ArrayCreate(AVISource(.1.), AVISource(.2.))
a1 = a1.ArrayInsert(AVISource(.3.))
a1 = a1.ArrayInsert(AVISource(.4.), 0)
# a1 now contains clips {(.4.),(.1.),(.2.),(.3.)}

ArrayLen
Module: array :: core
Definition:
ArrayLen(string array)

Description:
Returns the length of array, ie the number of elements stored inside it.

Examples:
a1 = "0.5, 1.0, 1.5, 2.0, 2.5"
items = a1.ArrayLen() # items == 5
a2 = ""
itm2 = a2.ArrayLen() # itm2 == 0
ArrayRange
Module: array :: core
Definition:
ArrayRange(val start, val end, val "step", int "npoints")

Description:
Returns an array with values covering the range [start..end] either with a specified step or with a specified number
of points (when the optional npoints parameter is specified).
Arguments:
start: The start value of the range (int or float).
end: The end value of the range (int or float).
"step" (Optional, defaults to 1): The step value to add in each successive step until end is reached.
"npoints" (Optional): The number of points (array elements) to divide the specified range ([start..end]).
Notes and conditions on arguments relations:
1] step and npoints cannot be specified together (the function will throw an error).
2] When step is defined and the values of start and step are such that end cannot exactly be reached by succesively
addind step to start then the maximum valid value < end will be the last element of the returned array.
This is of importance when float values are used, since then small approximation errors inherent to float
arithmetic may result in arrays with one less element than the number expected by the arguments. If this happens,
add a small number to end (for example 0.0001) in order to get the expected number of array elements.

Examples:
a1 = ArrayRange(0, 10)
# a1 == "0,1,2,3,4,5,6,7,8,9,10"
a2 = ArrayRange(0, 10, 2)
# a2 == "0,2,4,6,8,10"
a3 = ArrayRange(0, 10, 3)
# a3 == "0,3,6,9"
a4 = ArrayRange(0, 10, npoints=5)
# a4 == "0,2.5,5.0,7.5,10.0"
ArraySet
Module: array :: core
Definition:
ArraySet(string array, int index, val new_value)

Description:
Assigns new_value to the array element with index index and returns the resulting array.
This is the equivalent of the array[index] = value statement used in many programming languages, where valid
indexes are in the range [0..ArrayLen(array)-1].

Examples:
a1 = "2.3,4,5,1.2,3"
a1 = a1.ArraySet(4, 12) # a1 == "2.3,4,5,1.2,12"
a1 = a1.ArraySet(1, 0.2) # a1 == "2.3,0.2,5,1.2,12"

ArraySetValueRegisterNewHandler
Module: array :: core
Definition:
ArraySetValueRegisterNewHandler(string new_handler)

Description:
Makes new_handler the new array value-set handler function by assigning it to the ArraySetValueHandler global
variable.
Returns the previous value of the variable.
The assignment is made only if the passed argument is callable, as decided by the IsCallable() library function.
Note that this is a global setting affecting immediately all subsequent operations on arrays.

Examples:
function my_array_set_handler(...) {...}
...
oldhandler = ArraySetValueRegisterNewHandler("my_array_set_handler")
# perform your custom array operations here
...
# if afterwards you want the previous behavior, reset the old handler
dummy = ArraySetValueRegisterNewHandler(oldhandler)
ArraySetValueResetDefaultHandler
Module: array :: core
Definition:
ArraySetValueResetDefaultHandler()

Description:
Resets the array value-set handler function to the default AVSLib handler by assigning it to the
ArraySetValueHandler global variable.
Returns the previous value of the variable.
Note that this is a global setting affecting immediately all subsequent operations on arrays.

Examples:
function my_array_set_handler(...) {...}
...
oldhandler = ArraySetValueRegisterNewHandler("my_array_set_handler")
# pdrform your custom array operations here
...
# if afterwards you want the default behavior, reset the handler
dummy = ArraySetValueResetDefaultHandler()
The array :: functions module
The array :: functions module provides functions, constants and global variables for the performance of common
array operations such as comparisons, negation, product, average, etc.

Required modules
base :: core, numeric :: core, array :: core, array :: operators

Functions
Name Description
ArrayAverage() Returns the (statistical) average of all array elements...

ArrayClamp() Applies the Clamp function to all array elements and returns the result...

ArrayEqual() Returns true if all corresponding elements of the arrays ...

ArrayGreater() Returns true if all elements of array1 are greater than the corresponding ...

ArrayGreaterOrEqual() Returns true if all elements of array1 are greater or equal than ...

ArrayLess() Returns true if all elements of array1 are less than ...

ArrayLessOrEqual() Returns true if all elements of array1 are less or equal than ...

ArrayNegate() Inverses the sign of all elements of array (the same as multiplying...

ArrayNot() Applies the Not function to all array elements ...

ArrayNotEqual() Returns true if all corresponding elements of array1 ...

ArrayProduct() Returns the product of all array elements...

ArraySpline() Returns an array with elements the spline (y value) of ...

ArrayStDev() Returns the standard deviation of array elements...

ArraySumProduct() Returns the sum of the products of all pairs of the corresponding elements ...

Constants
None

Variables
None
ArrayAverage
Module: array :: functions
Definition:
ArrayAverage(string array)

Description:
Returns the (statistical) average of all array elements.

Examples:
a1 = "6, 5, 7, 9, 4, 8"
avg = ArrayAverage(a1)
# avg is now 6.5000, ie 39/6

ArrayClamp
Module: array :: functions
Definition:
ArrayClamp(string array, val low_limit, val high_limit)

Description:
Applies the Clamp function to all array elements and returns the resulting array.

Examples:
ax = "3, 5, -8, 12, 4, 2, 10"
ac = ax.ArrayClamp(2, 7) # same as ArrayClamp(ax, 2, 7)
# ac is now "3, 5, 2, 7, 4, 2, 7"

ArrayEqual
Module: array :: functions
Definition:
ArrayEqual(string array1, string array2)

Description:
Returns true if all corresponding elements of the arrays passed as arguments are equal (ie array1[i] == array2[i]
for all i).

Examples:
a1 = "0.5, 1.0, 1.5, 2.0, 2.5"
a2 = "0.5, 1.0, -1.5, 2.0, 2.5"
a3 = a1
b1 = ArrayEqual(a1, a2) # b1 == false
b2 = ArrayEqual(a1, a3) # b2 == true
ArrayGreater
Module: array :: functions
Definition:
ArrayGreater(string array1, string array2)

Description:
Returns true if all elements of array1 are greater than the corresponding elements of array2 (ie array1[i] >
array2[i] for all i).

Examples:
a1 = "2,3,6,8,12,5,4"
a2 = "1,2,5,7,11,4,3"
a3 = "2,2,5,7,12,5,4"
b1 = a1.ArrayGreater(a2) # b1 == true
b2 = a1.ArrayGreater(a3) # b2 == false

ArrayGreaterOrEqual
Module: array :: functions
Definition:
ArrayGreaterOrEqual(string array1, string array2)

Description:
Returns true if all elements of array1 are greater or equal than the corresponding elements of
array2 (ie array1[i] >= array2[i] for all i).

Examples:
a1 = "2,3,6,8,12,5,4"
a2 = "10,2,5,7,21,4,13"
a3 = "2,2,5,7,12,5,4"
b1 = a1.ArrayGreaterOrEqual(a2) # b1 == false
b2 = a1.ArrayGreaterOrEqual(a3) # b2 == true
ArrayLess
Module: array :: functions
Definition:
ArrayLess(string array1, string array2)

Description:
Returns true if all elements of array1 are less than the corresponding elements of array2 (ie array1[i] < array2[i]
for all i).
Examples:
a1 = "2,3,6,8,12,5,4"
a2 = "1,2,5,7,11,4,3"
a3 = "2,2,5,7,12,5,4"
b1 = a2.ArrayLess(a1) # b1 == true
b2 = a2.ArrayLess(a3) # b2 == false

ArrayLessOrEqual
Module: array :: functions
Definition:
ArrayLessOrEqual(string array1, string array2)

Description:
Returns true if all elements of array1 are less or equal than the corresponding elements of
array2 (ie array1[i] <= array2[i] for all i).

Examples:
a1 = "2,3,6,8,12,5,4"
a2 = "10,2,5,7,21,4,13"
a3 = "2,2,5,7,12,5,4"
b1 = a3.ArrayLessOrEqual(a1) # b1 == true
b2 = a3.ArrayLessOrEqual(a2) # b2 == false
ArrayNegate
Module: array :: functions
Definition:
ArrayNegate(string array)

Description:
Inverses the sign of all elements of array (the same as multiplying with -1) and returns the resulting array.

Examples:
a1 = "2,3,5,1.45,-23,-2.4,4"
a2 = a1.ArrayNegate() # a2 == "-2,-3,-5,-1.45,23,2.4,-4"
a3 = ArrayOpArray(a1, a2, "+")
# a3 contains all zeros [a1 + (-a1) = 0]

ArrayNot
Module: array :: functions
Definition:
ArrayNot(string array)

Description:
Applies the Not function to all array elements (ie performs a NOT to array elements) and returns the resulting
array.

Examples:
a1 = "true,true,false,true"
a2 = a1.ArrayNot()
# a2 == "false,false,true,false"
ArrayNotEqual
Module: array :: functions
Definition:
ArrayNotEqual(string array1, string array2)

Description:
Returns true if all corresponding elements of array1 and array2 are not equal (ie array1[i] != array2[i] for all i).

Examples:
a1 = "2,3,4,5,6,7"
a2 = "2,3,5,-6,7,8"
a3 = "3,4,-5,6,-7,8"
b1 = a1.ArrayNotEqual(a2) b1 == false
b2 = a1.ArrayNotEqual(a3) b2 == true
b3 = ArrayNotEqual(a2, a3) b3 == false

ArrayProduct
Module: array :: functions
Definition:
ArrayProduct(string array)

Description:
Returns the product of all array elements.

Examples:
a1 = "1,2,-3,4,-2,5"
pr = a1.ArrayProduct() # pr == 240
a2 = "0.1,0.2,-3.5,4,-2.0,5.2"
pf = a2.ArrayProduct() # pf == 2.912
ArraySpline
Module: array :: functions
Definition:
ArraySpline(string x_array, string point_curve, bool "cubic")

Description:
Returns an array with elements the spline (y value) of each respective x_array's element.
point_curve must be an array of x,y coordinates, as in Spline standard Avisynth function.

Examples:
clp = AVISource(...)
ovr = AVISource(...)
fr = "25,50,75,100"
x = "50,100,240,290"
crv = "20,30,80,240,160,120,320,70"
y = x.ArraySpline(crv, true)
anm = PolygonAnim(clp, ovr, fr, x, y)

ArrayStDev
Module: array :: functions
Definition:
ArrayStDev(string array)

Description:
Returns the standard deviation of array elements.
array must contain only numbers, else the function will throw an error or the results will be unpredictable.

Examples:
a1 = "1, 1, 2, 0, 1"
sd = a1.ArrayStDev() # sd == 0.7071
ArraySumProduct
Module: array :: functions
Definition:
ArraySumProduct(string array1, string array2)

Description:
Returns the sum of the products of all pairs of the corresponding elements of array1 and array2.
In effect (taking into account that an array is the representation of a vector) the function is the equivalent of the
internal product of two vectors.

Examples:
a1 = "0.5, 1.0, 1.5, 2.0, 2.5"
ip = ArraySumProduct(a1, a1) # ip == 13.75
The array :: operators module
The array :: operators module provides functions, constants and global variables for the implementation of
array operators, the core mechanism for performing operations on arrays.

Required modules
string :: core, array :: core

Functions
Name Description
ArrayOpArray() Performs an operation between corresponding elements of two arrays ...

Performs an operation of a function onto all pairs of corresponding elements of


ArrayOpArrayFunc()
two arrays...

ArrayOpFunc() Performs an operation of a function onto all elements of an array ...

ArrayOpValue() Performs an operation of a value with all elements of an array ...

ArraySum() Returns the sum of all array elements as it is deduced by applying a ...

Constants
None

Variables
None
ArrayOpArray
Module: array :: operators
Definition:
ArrayOpArray(string array1, string array2, string operation)

Description:
Performs an operation between corresponding elements of two arrays (ie array1[i] op array2[i]) and returns the
resulting array.

Arguments:
array1: The array who's elements will be the left operand of the operation.
array2: The array who's elements will be the right operand of the operation.
operation: The string representation of the operation to be performed between array1 and array2 pairs of
elements. All Avisynth operations that are valid for the specific type of elements are supported ("+", "-", "*", "/",
"%", "==", "!=", ">=", "<=", "<", ">", "&&", "||", etc.)

Notes and conditions on arguments relations:


1] The type of array1 and of array2 elements must be compatible with respect to the chosen operation.
2] When performing division with ints Avisynth truncates the result to an int. If you want float results, make either
array1 or array2 elements floats (you can use a call like this: ArrayOpFunc(my_array, "Float") ).

Examples:
a1 = "2,3,5,-6,7,8"
a2 = "3,4,-5,6,-7,8"
c1 = AVISource(...)
...
c6 = AVISource(...)
a3 = ArrayCreate(c1, c2, c3)
a4 = ArrayCreate(c4, c5, c6)
r1 = ArrayOpArray(a1, a2, "+") # r1 == "5,7,0,0,0,16"
r2 = ArrayOpArray(a1, a2, "-") # r2 == "-1,-1,10,-12,14,0"
r3 = ArrayOpArray(a1, a2, "<=") # r3 == "true,true,false,true,false,true"
r4 = ArrayOpArray(a3, a4, "+")
# r4 contains clips {(c1+c4),(c2+c5),(c3+c6)}
ArrayOpArrayFunc
Module: array :: operators
Definition:
ArrayOpArrayFunc(string array1, string array2, string func, string "args")
Description:
Performs an operation of a function onto all pairs of corresponding elements of two arrays (ie func(array1[i],
array2[i], ...)) and returns the resulting array. Arguments:
array1: The array who's elements will be the first argument of func.
array2: The array who's elements will be the second argument of func.
func: The name of a function that accepts two required arguments and possibly an arbitrary number of optional
arguments (see args, below).
"args" (Optional, defaults to ""): A string in the form of a function call argument list (ie a comma delimited list of
values) containing additional arguments to be passed to the func function.
Notes and conditions on arguments relations:
1] func must accept two required argument with types compatible to array1 and array2 elements' type(s). The
arguments must be the first in func's argument list. An arbitrary number of other (possibly optional) arguments is
allowed, but if any of them is not optional it must always be specified in args.
2] The types of array1 and array2 elements need not be the same. The only requirement is that func can accept
them.
3] The args argument list string can only contain value literals and global names (expressions of them are
supported also). Use the String() function to convert local variables to value literals.

Examples:
Function xrot(int x, int y, float angle) {
return Round(x*Cos(angle) - y*Sin(angle))
}
Function yrot(int x, int y, float angle) {
return Round(x*Sin(angle) + y*Cos(angle))
}
# lets define a curve and rotate it by 30 degrees
xs = "0,40,80,120,160,200,240"
ys = "0,40,120,220,280,320,340"
xs_30 = ArrayOpArrayFunc(xs, ys, "xrot", String(Pi()/6))
ys_30 = ArrayOpArrayFunc(xs, ys, "yrot", String(Pi()/6))
...
# function to extract a number of frames from a clip
Function mytrim(clip c, int frames) { return c.Trim(0, -frames) }
# lets create arrays of clips and frames
# and then perform a batch Trim on all clips
ac = ArrayCreate(AVISource(.1.), ..., AVISource(.8.))
fn = "400,300,400,500,1200,600,400,900"
ac_trim = ArrayOpArrayFunc(ac, fn, "mytrim") # done
ArrayOpFunc
Module: array :: operators
Definition:
ArrayOpFunc(string array, string func, string "args")

Description:
Performs an operation of a function onto all elements of an array (ie func(array[i], ...)) and returns the resulting
array.
Arguments:
array: The array who's elements will be the first argument of func.
func: The name of a function that accepts one required argument and possibly an arbitrary number of optional
arguments (see args, below).
"args" (Optional, defaults to ""): A string in the form of a function call argument list (ie a comma delimited list of
values) containing additional arguments to be passed to the func function.

Notes and conditions on arguments relations:


1] func must accept one required argument with type compatible to array elements' type(s). The argument must be
first in func's argument list. An arbitrary number of other (possibly optional) arguments is allowed, but if any of
them is not optional it must always be specified in args.
2] The args argument list string can only contain value literals and global names (expressions of them are
supported also). Use the String() function to convert local variables to value literals.

Examples:
Function my_y(int x) { return Round(10 + 0.5*x - 0.1*Pow(x, 2)) }
ax = ArrayRange(0, 700, 50)
ay = ax.ArrayOpFunc("my_y")
# filter a set of clips
Function my_f(clip c, float f_hue) {
return c.ConvertToYV12().BilinearResize( \
720, 480).Tweak(hue=f_hue)
}
ac1 = ArrayCreate(AVISource(.1.), AVISource(.2.), ...)
ac2 = ac1.ArrayOpFunc("my_f", "25") # set f_hue to 25
ArrayOpValue
Module: array :: operators
Definition:
ArrayOpValue(string array, val scalar, string operation, bool "array_first")

Description:
Performs an operation of a value with all elements of an array (ie value op array[i] or array[i] op value) and
returns the resulting array.
Arguments:
array: The array who's elements will be the one (defaults to left) operand of the operation.
scalar: The single value which will be the other (defaults to right) operand of the operation.
operation: The string representation of the operation to be performed between each array element and scalar. All
Avisynth operations that are valid for the specific types of operands are supported ("+", "-", "*", "/", "%", "==", "!
=", ">=", "<=", "<", ">", "&&", "||", etc.)
"array_first" (Optional, defaults to true): Bool flag that controls the order of the operands of the operation.
When true or ommited, the array element will be the left operand and the scalar the right one. When false, the
order is reversed.
This is of importance for operations that are not symmetrical, such as for example division ("/"), modulo ("%"),
certain comparison operations (">", "<", ">=", "<="), etc.

Notes and conditions on arguments relations:


1] The type of array elements and of scalar must be compatible with respect to the chosen operation.
2] When performing division with ints Avisynth truncates the result to an int. If you want float results, make either
array elements or scalar a float.

Examples:
a1 = "3.2, 4.1, 3.3, -0.23"
a2 = a1.ArrayOpValue(0.4, "+") # a2 == "3.6,4.5,3.7,0.17"
a3 = a1.ArrayOpValue(4, "<=") # a3 == "true,false,true,true"
# now we will invert the order of operands
# which is the same as changing the operation to ">="
a3 = a1.ArrayOpValue(4, "<=", false) # a3 == "false,true,false,false"
# clips can also be added
ac1 = ArrayCreate(AVISource(.1.), AVISource(.2.), ...)
clp = AVISource(...)
# add clp in front of every clip contained in ac1
ac2 = ac1.ArrayOpValue(clp, false)
# add clp both in front and at end of every clip contained in ac1
ac3 = ac1.ArrayOpValue(clp, false).ArrayOpValue(clp)
ArraySum
Module: array :: operators
Definition:
ArraySum(string array, string "elm_func", string "elm_args", string "sum_func", string "sum_args")
Description:
Returns the sum of all array elements as it is deduced by applying a user-defined function for the evaluation of
each array element and another one for the summing of the resulting values.
In effect the function is the equivalent of taking the integral of an array.
Arguments:
array: The array who's elements will be summed.
"elm_func" (Optional, defaults to "Self"): The function to evaluate each array element and return a value to be
used by sum_func. The default function simply returns element unchanged.
"elm_args" (Optional, defaults to ""): A string in the form of a function call argument list (ie a comma delimited
list of values) containing additional arguments to be passed to the elm_func function.
"sum_func" (Optional, defaults to "Sum2"): The function to evaluate the sum of values produced by the
application of elm_func on each array element. The default function simply adds the values by using the "+"
operator.
"sum_args" (Optional, defaults to ""): A string in the form of a function call argument list (ie a comma delimited
list of values) containing additional arguments to be passed to the sum_func function.
Notes and conditions on arguments relations:
1] elm_func must accept one required argument with type compatible to array elements' type(s). The argument
must be first in elm_func's argument list. An arbitrary number of other (possibly optional) arguments is allowed,
but if any of them is not optional it must always be specified in elm_args.
2] sum_func must accept two required arguments with types compatible to the type(s) of the result of application
of elm_func to array's elements. The arguments must be first in sum_func's argument list. An arbitrary number of
other (possibly optional) arguments is allowed, but if any of them is not optional it must always be specified in
sum_args.
3] Both the elm_args and sum_args argument list strings can only contain value literals and global names
(expressions of them are supported also). Use the String() function to convert local variables to value literals.
Examples:
a1 = "0.5, 1.0, 1.5, 2.0, 2.5"
num = a1.ArraySum() # num == 7.5
# sum an array of clips
a2 = ArrayCreate(AVISource(.1.), ..., AVISource(.20.))
fin_clip = a2.ArraySum() # same as (.1.)+(.2.)+...
# filter and then sum an array of clips
Function myfilter(clip c) {
return c.ConvertToYUY2().Tweak(cont=1.2)
}
flt_clip = a2.ArraySum(elm_func="myfilter")
# filter and then sum an array of clips
# blending with Dissolve(...,10)
blflt_clip = a2.ArraySum(elm_func="myfilter", \
sum_func="Dissolve", sum_args="10")
The array :: powseries module
The array :: powseries module provides functions, constants and global variables for the implementation of
additional power series functions, besides the core one (PowSeries()).

Required modules
string :: core, array :: core, array :: operators

Functions
Name Description
ArrayPowSeries() Applies the PowSeries function to all array elements and returns th...

ArrayPowSeriesA() Applies the PowSeriesA function to all array elements and returns ...

ArrayPowSeriesAA() Applies the PowSeriesAA function to all array elements and return...

PowSeriesA() Returns a power series of x with coefficients supplied by an array...

PowSeriesAA() Returns a power series of x with coefficients and powers supplied by ...

Constants
None

Variables
None
ArrayPowSeries
Module: array :: powseries
Definition:
ArrayPowSeries(
string x_array, string coef_func, string power_func, int start_index, int end_index,
int "increment", string "coef_args", string "power_args")
Description:
Applies the PowSeries function to all array elements and returns the resulting array.

Examples:
function mycoef(int i) { return Pow(2, i) / Factorial(i) }
function mypow(int i) { return 2 * i + 1 }
ax = ArrayRange(0.1, 1.0, 0.1)
ay = ax.ArrayPowSeries("mycoef", "mypow", 0, 4)

ArrayPowSeriesA
Module: array :: powseries
Definition:
ArrayPowSeriesA(string x_array, string coefs_array, val "start_power", val "increment")

Description:
Applies the PowSeriesA function to all array elements and returns the resulting array.

Examples:
coefs = "3, 0.2, -0.04, 0.0002"
ax = "0,50,100,150,200"
ay = ax.ArrayPowSeriesA(coefs)

ArrayPowSeriesAA
Module: array :: powseries
Definition:
ArrayPowSeriesAA(string x_array, string coefs_array, string powers_array)

Description:
Applies the PowSeriesAA function to all array elements and returns the resulting array.

Examples:
coefs = "0.6, 0.03, -0.0025"
powers = "1, 3, 5"
ax = "0,50,100,150,200"
ay = ax.ArrayPowSeriesAA(coefs, powers)
PowSeriesA
Module: array :: powseries
Definition:
PowSeriesA(val x, string coefs_array, val "start_power", val "increment")

Description:
Returns a power series of x with coefficients supplied by an array and powers of defined start and increment.
It is provided as a simpler alternative for series with small number of terms to the more generic PowSeries
function.
Arguments:
x: The value of which the power series will be calculated.
coefs_array: The array holding the power series coefficients.
"start_power" (Optional, defaults to 0): The starting power of the series.
"increment" (Optional, defaults to 1): The increment between successive powers of the series.
Notes and conditions on arguments relations:
1] If coefs_array has zero elements the function returns zero.

Examples:
# Calculate the power series 0.5*x + 3.23*x3 - 2.5*x5 for x = 5.4
coefs = "0.5, 3.23, -2.5"
f1 = PowSeriesA(5.4, coefs, 1, 2)

# Calculate the power series 3 + 2*x - 4*x2 + x3 for x = 2.5


coefs2 = "3, 2, -4, 1"
f2 = PowSeriesA(2.5, coefs2)

# Calculate the power series 1.3*x-0.5 + 0.2*x0.7 - 2.3*x1.9


# for x = 3
coefs3 = "1.3, 0.2, -2.3"
f3 = PowSeriesA(3, coefs3, -0.5, 1.2)
PowSeriesAA
Module: array :: powseries
Definition:
PowSeriesAA(val x, string coefs_array, string powers_array)

Description:
Returns a power series of x with coefficients and powers supplied by (two) respective arrays.
It is provided as a simpler alternative for series with small number of terms to the more generic PowSeries
function.
Arguments:
x: The value of which the power series will be calculated.
coefs_array: The array holding the power series coefficients.
powers_array: The array holding the powers of the series.

Notes and conditions on arguments relations:


1] coefs_array and powers_array must have the same number of elements.

Examples:
# Calculate the power series 0.5*x + 3.23*x3 - 2.5*x5 for x = 5.4
coefs = "0.5, 3.23, -2.5"
powers = "1, 3, 5"
f1 = PowSeriesAA(5.4, coefs, powers)

# Calculate the power series 1.3*x-0.52 + 0.22*x2.34 - 2.3*x12.91


# for x = 3.3
coefs2 = "1.3, 0.22, -2.3"
powers2 = "-0.52, 2.34, 12.91"
f2 = PowSeriesAA(3.3, coefs2, powers2)
The array :: properties module
The array :: properties module provides functions, constants and global variables for getting / setting common
array properties such as whether (or how many times) a value is contained in an array, etc.

Required modules
base :: core, base :: conversion, array :: core, array :: operators

Functions
Name Description
ArrayContains() Returns true if array contains at least one element with ...

ArrayElmCount() Returns the number of array elements with value value...

ArrayIndexOf() Returns the (first) index of array that contains the specified value...

ArrayMax() Returns the bigger value stored inside array...

ArrayMin() Returns the smaller value stored inside array...

Constants
None

Variables
None
ArrayContains
Module: array :: properties
Definition:
ArrayContains(string array, val value)

Description:
Returns true if array contains at least one element with value value, false otherwise.

Examples:
ar = ArrayCreate(4, 3, 2, 12, 3, 5)
b1 = ar.ArrayContains(4) # b1 == true
b2 = ar.ArrayContains(3) # b2 == true
b3 = ar.ArrayContains(7) # b3 == false

ArrayElmCount
Module: array :: properties
Definition:
ArrayElmCount(string array, val value)

Description:
Returns the number of array elements with value value.

Examples:
a = ArrayCreate(3,4,3,3,1,5,4,3,2)
n1 = a.ArrayElmCount(3) # n1 == 4
n2 = a.ArrayElmCount(4) # n2 == 2
ArrayIndexOf
Module: array :: properties
Definition:
ArrayIndexOf(string array, val value, int "start_from")

Description:
Returns the (first) index of array that contains the specified value.
The start_from optional argument (defaults to 0) determines the index from which searching will start.
If no match is found the function returns -1.

Examples:
a = ArrayCreate(2,3,4,5,2,4)
n1 = a.ArrayIndexOf(2) # n1 == 0
n2 = a.ArrayIndexOf(4) # n2 == 2
n3 = a.ArrayIndexOf(2,1) # n3 == 4
n4 = a.ArrayIndexOf(0) # n4 == -1

ArrayMax
Module: array :: properties
Definition:
ArrayMax(string array)

Description:
Returns the bigger value stored inside array.

Examples:
a1 = "0.5, 1.0, 1.5, 2.0, 2.5"
a2 = a1.ArraySet(3, 3.7)
mx1 = ArrayMax(a1) # mx1 == 2.5
mx2 = a2.ArrayMax() # mx2 == 3.7
ArrayMin
Module: array :: properties
Definition:
ArrayMin(string array)

Description:
Returns the smaller value stored inside array.

Examples:
a1 = "0.5, 1.0, 1.5, 2.0, 2.5"
a2 = a1.ArraySet(3, -3.7)
mx1 = ArrayMin(a1) # mx1 == 0.5
mx2 = a2.ArrayMin() # mx2 == -3.7
The array :: slices module
The array :: slices module provides functions, constants and global variables for the implementation of operations
on array slices (ie subranges) such as selection, deletion, replacement, etc.

Required modules
base :: core, string :: core, array :: core

Functions
Name Description
ArrayDelRange() Deletes a range of elements from the array passed as argument and ...

Demultiplexes the array passed as argument and returns the speficied subarray (to
ArrayDeplex()
multiplex ...

ArrayGetRange() Retrieves a range of elements (a subarray) from array ...

ArrayInsRange() Inserts the elements of newval_array before array[index] and returns the ...

ArrayJoin() Joins the arrays passed as arguments (arr01, arr02, ...) serially, ...

ArrayPlex() Multiplexes the arrays passed as arguments (arr01, arr02, ...) and ...

ArraySetRange() Assigns new values to a range of elements (subarray) of array and ...

ArraySplit() Splits array to a specified number of parts or to parts with specified length ...

Constants
None

Variables
None
ArrayDelRange
Module: array :: slices
Definition:
ArrayDelRange(string array, int "start_index", int "end_index")

Description:
Deletes a range of elements from the array passed as argument and returns the resulting array.
Arguments:
array: The array to operate on.
"start_index" (Optional, defaults to 0, ie the first array element): The index of the array element to start deleting
from.
"end_index" (Optional, defaults to ArrayLen(array), ie one position past the last array element): The index of the
array element to stop deleting (this element is not deleted).

Examples:
a1 = "0.5, 1.0, 1.5, 2.0, 2.5"
a2 = a1.ArrayDelRange() # a2 == "" (empty array)
a3 = a1.ArrayDelRange(0, 2) # a3 == "1.5,2,2.5"
a4 = a1.ArrayDelRange(3) # a4 == "0.5,1,1.5"
a5 = a1.ArrayDelRange(end_index=3) # a5 == "2,2.5"
ArrayDeplex
Module: array :: slices
Definition:
ArrayDeplex(string array, int index, int num_plexed_arrays)

Description:
Demultiplexes the array passed as argument and returns the speficied subarray (to multiplex arrays use
ArrayPlex).

Arguments:
array: The array to operate on.
index: The index of the demultiplexed subarray of array to return as result. Must be in the range
[0..num_plexed_arrays).
num_plexed_arrays: The number of multiplexed subarrays that array holds.

Notes and conditions on arguments relations:


Demultiplexing is performed by dividing array into blocks of num_plexed_arrays elements and taking the index
element of each block, appending it to the resulting array.
In effect the function treats array as a matrix of num_plexed_arrays columns and returns its index column.

Examples:
coords = "10,20,30,70,50,120,70,140,90,100,110,80"
# assuming coords is a [x,y] matrix (2x6), get x and y
ax = coords.ArrayDeplex(0, 2)
# ax == "10,30,50,70,90,110"
ay = coords.ArrayDeplex(1, 2)
# ay == "20,70,120,140,100,80"
...
# assuming coords is a [x,y,z] matrix (3x4), get z
z = coords.ArrayDeplex(2, 3)
# z == "30,120,90,80"
ArrayGetRange
Module: array :: slices
Definition:
ArrayGetRange(string array, int "start_index", int "end_index")

Description:
Retrieves a range of elements (a subarray) from array and returns it as a new array. The function returns all
elements contained in [start_index..end_index) ie the element array[end_index] is not returned.

Arguments:
array: The array to retrieve the element range (subarray) from.
"start_index" (Optional, defaults to 0): The starting index of the element range that will be retrieved.
"end_index" (Optional, defaults to array. ArrayLen()): The ending index of the element range that will be
retrieved.

Examples:
a1 = "0.5, 1.0, 1.5, 2.0, 2.5"
a2 = a1.ArrayGetRange() # a2 == a1
a3 = a1.ArrayGetRange(0, 2) # a3 == "0.5,1"
a4 = a1.ArrayGetRange(3) # a4 == "2,2.5"
a5 = a1.ArrayGetRange(end_index=3) # a5 == "0.5,1,1.5"

ArrayInsRange
Module: array :: slices
Definition:
ArrayInsRange(string array, string newval_array, int "index")

Description:
Inserts the elements of newval_array before array[index] and returns the resulting array.
As a result the array is expanded, newval_array's elements are positioned at array[index] - array[index +
ArrayLen(newval_array) - 1] and all subsequent elements's indexes are increased by ArrayLen(newval_array).
If (optional) index is ommited, then newval_array's elements are appended to the end of array (same as providing
an index with value equal to array. ArrayLen()).

Examples:
a1 = ArrayCreate(AVISource(.1.), AVISource(.2.), , AVISource(.3.))
a2 = ArrayCreate(AVISource(.4.), AVISource(.5.))
a3 = a1.ArrayInsRange(a2, 1)
# a3 now contains clips {(.1.),(.4.),(.5.),(.2.),(.3.)}
a4 = a1.ArrayInsRange(a2)
# a4 now contains clips {(.1.),(.2.),(.3.),(.4.),(.5.)}
ArrayJoin
Module: array :: slices
Definition:
ArrayJoin(string "arr01", string "arr02", string "arr03", string "arr04", ... , string "arr20")

Description:
Joins the arrays passed as arguments (arr01, arr02, ...) serially, in the order specified, into one array. Returns the
resulting array.

Notes and conditions on arguments relations:


1] If none argument is supplied, the function returns an empty array (ie an array with zero elements).

Examples:
a1 = ArrayCreate(AVISource(.1.), AVISource(.2.), AVISource(.3.))
a1 = a1.ArrayInsert(AVISource(.4.), 0)
# a1 now contains clips {(.4.),(.1.),(.2.),(.3.)}
a2 = a1.ArrayInvert()
# a2 now contains clips {(.3.),(.2.),(.1.),(.4.)}
a3 = ArrayJoin(a1, a2)
# a3 now contains clips {(.4.),(.1.),(.2.),(.3.),(.3.),(.2.),(.1.),(.4.)}
a4 = ArrayJoin(a2, a1)
# a4 now contains clips {(.3.),(.2.),(.1.),(.4.),(.4.),(.1.),(.2.),(.3.)}
ArrayPlex
Module: array :: slices
Definition:
ArrayPlex(string arr01, string arr02, string "arr03", string "arr04", ... , string "arr20")

Description:
Multiplexes the arrays passed as arguments (arr01, arr02, ...) and returns the resulting array. [1]
Multiplexing is performed by taking sequentially one element of each array and appending it to the resulting array.
In effect the function creates a matrix with each array being a column of the matrix, in the order that they are
passed to the function.

Examples:
ax = ArrayRange(0, 500, 50)
# y coordinates
ay = "0,100,160,210,240,250,260,250,240,220,190"
# (x,y) coordinates
coords = ArrayPlex(ax, ay)
# coords == "0,0,50,100,100,160,150,210,..."
# or in a more visually evident arrangement
# "0,0,\
# 50,100,\
# 100,160,\11`
# ..."

[1]: Thefunction can handle up to 20 arguments. This number is chosen as a good balance between usability and
speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array
package.
ArraySetRange
Module: array :: slices
Definition:
ArraySetRange(string array, string newval_array, int "start_index", int "end_index")

Description:
Assigns new values to a range of elements (subarray) of array and returns the resulting array. The function sets all
elements contained in [start_index..end_index) ie the element array[end_index] is not set.
Arguments:
array: The array to set the element range (subarray) of.
newval_array: The array with the new values that array's element range will be assigned to.
"start_index" (Optional, defaults to 0): The starting index of the element range that will be set.
"end_index" (Optional, defaults to array.ArrayLen()): The ending index of the element range that will be set.
Notes and conditions on arguments relations:
1] newval_array need not have the same number of elements as the selected subarray of array. However, if that
happens the new array will have different length (number of elements) from the original.

Examples:
a1 = "1,2,3,4,5,6,7,8,9"
a2 = a1.ArraySetRange("10,11,12", 3, 6)
# a2 == "1,2,3,10,11,12,7,8,9"
a3 = a1.ArraySetRange("10,11,12", 3, 4)
# a2 == "1,2,3,10,11,12,5,6,7,8,9"
a4 = a1.ArraySetRange("10,11,12", 3, 9)
# a2 == "1,2,3,10,11,12"
a5 = a1.ArraySetRange("10,11,12", 1, 6).ArraySet("-1,-2", 4, 6)
# a5 == "1,10,11,12,-1,-2,9"
ArraySplit
Module: array :: slices
Definition:
ArraySplit(string array, int index, int "chunks", int "chunksize")

Description:
Splits array to a specified number of parts or to parts with specified length (ie number of elements) and returns the
requested part.
Arguments:
array: The array to split.
index: The zero-based index of the array part to return.
If chunks is specified, index must be in the range [0..chunks - 1].
If chunksize is specified, index must be in the range [0..Ceil(ArrayLen(array) / chunksize) - 1].
"chunks" (Optional): The number of parts to split array to.
"chunksize" (Optional): The number of elements that each array part should have.

Notes and conditions on arguments relations:


1] Exactly one of the chunks, chunksize arguments must be specified. If none or both are specified the function
will throw an error.
2] If chunks is specified all parts except the last will have Floor(ArrayLen(array) / chunks) elements.
3] If chunksize is specified all parts except the last will have chunksize elements.
4] In any case the last part will contain the remaining array elements (which number may be equal to that of the
other parts for certain combinations of array length and chunks or chunksize but in general will not).

Examples:
a1 = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16"
# Splitting a 17-element array in 5 chunks yields
# four 3-element arrays and a last 5-element array.

a2 = a1.ArraySplit(0, 5) # a2 == "0,1,2"
a3 = a1.ArraySplit(2, 5) # a3 == "6,7,8"
a4 = a1.ArraySplit(4, 5) # a4 == "12,13,14,15,16"

# Splitting a 17-element array with chunksize 4 yields


# four 4-element arrays and a last 1-element array.

a5 = a1.ArraySplit(0, chunksize=4) # a5 == "0,1,2,3"


a6 = a1.ArraySplit(2, chunksize=4) # a6 == "8,9,10,11"
a7 = a1.ArraySplit(4, chunksize=4) # a7 == "16"
The array :: transforms module
The array :: transforms module provides functions, constants and global variables for the implementation of array
transformations such as inversion, sorting, etc.

Required modules
base :: core, string :: core, numeric :: statistics, array :: core, array :: operators, array :: slices

Functions
Name Description
ArrayDistinct() Returns the subset of array with only distinct elements in it. The resulting...

Returns a new array with the elements in indices index1, index2 interchanged (ie
ArrayElmSwap()
array[index1] ...

ArrayInvert() Inverts the indexes of the elements of array (the last element ...

Removes elements from array, wherever the corresponding flags array element
ArrayReduce()
has a value equal t...

ArrayRotate() Rotates the indexes of the elements of array (ie it shifts all elements ...

ArraySort() Sorts array, using the quick sort algorithm ...

Constants
None

Variables
None
ArrayDistinct
Module: array :: transforms
Definition:
ArrayDistinct(string array, string "cmp_func", string "cmp_args", string "avg_func", string "avg_args")

Description:
Returns the subset of array with only distinct elements in it. The resulting array is always returned in ascending
sort order (ie a[i] < a[i+1] for all i).
Arguments:
array: The array from which distinct elements are sought.
cmp_func (optional): A custom comparison function which must accept two val arguments at the start of its list
and return -1,0,1 if arg1 < arg2, arg1 == arg2, arg1 > arg2, respectively.
cmp_args (optional): Any extra arguments needed by cmp_func as a string.
avg_func (optional): A custom average function (to be used by the sorting algorithm) which must accept two val
arguments at the start of its list and return the average value of them.
avg_args (optional): Any extra arguments needed by avg_func as a string.

Examples:
a1 = ArrayCreate(1,2,3,2,3,3,5,6,7,8,5,5,6)
a2 = a1.ArrayDistinct()
# a2 == "1,2,3,5,6,7,8"

ArrayElmSwap
Module: array :: transforms
Definition:
ArrayElmSwap(string array, int index1, int index2)

Description:
Returns a new array with the elements in indices index1, index2 interchanged (ie array[index1] now holds the
value of array[index2] at the original array and vice versa).

Examples:
a1 = ArrayCreate(1,2,3,4)
a2 = a1.ArrayElmSwap(0,1) # a2 == "2,1,3,4"
a3 = a2.ArrayElmSwap(2,3) # a3 == "2,1,4,3"
a4 = a3.ArrayElmSwap(0,3) # a4 == "4,1,3,2"
ArrayInvert
Module: array :: transforms
Definition:
ArrayInvert(string array)

Description:
Inverts the indexes of the elements of array (the last element becomes first and so on) and returns the resulting
array.

Examples:
a1 = ArrayCreate(AVISource(.1.), AVISource(.2.))
a1 = a1.ArrayInsert(AVISource(.3.))
a1 = a1.ArrayInsert(AVISource(.4.), 0)
# a1 now contains clips {(.4.),(.1.),(.2.),(.3.)}
a2 = a1.ArrayInvert()
# a2 now contains clips {(.3.),(.2.),(.1.),(.4.)}

ArrayReduce
Module: array :: transforms
Definition:
ArrayReduce(string array, string flags)

Description:
Removes elements from array, wherever the corresponding flags array element has a value equal to zero. Returns
the modified array.

Notes and conditions on arguments relations:


1] Both array and flags arrays must have the same length, else the function will throw an error.

Examples:
a1 = ArrayCreate(2.5, 3.12, 0.34, 2.15, 4, 5.1)
flags = ArrayCreate(1, -1, 0, 2, 0, 0)
a3 = a1.ArrayReduce(flags)
# a3 == "2.5, 3.12, 2.15"
ArrayRotate
Module: array :: transforms
Definition:
ArrayRotate(string array, int num_indexes)

Description:
Rotates the indexes of the elements of array (ie it shifts all elements either left or right and puts the overflowed
elements' block at the opposite side of the array). Returns the resulting array.

Arguments:
array: The array to rotate.
num_indexes: The number of indexes (ie positions) to rotate array elements.
If > 0 the rotation is made towards the end of the array (the elements are right-shifted and the last block is moved
to array's start). If < 0 the rotation is made towards the start of the array (the elements are left-shifted and the first
block is moved to array's end).

Notes and conditions on arguments relations:


1] If num_indexes > array.ArrayLen() the modulo of the division with array.ArrayLen() is used.

Examples:
a1 = "1,2,3,4,5,6,7,8,9,10"
a2 = a1.ArrayRotate(4) # a2 == "7,8,9,10,1,2,3,4,5,6"
a3 = a1.ArrayRotate(-4) # a3 == "5,6,7,8,9,10,1,2,3,4"
a4 = a1.ArrayRotate(12) # a4 == "9,10,1,2,3,4,5,6,7,8"
ArraySort
Module: array :: transforms
Definition:
ArraySort(string array, bool "ascending", string "cmp_func", string "cmp_args",
string "avg_func", string "avg_args")

Description:
Sorts array, using the quick sort algorithm [1].
Arguments:
array: The array to sort.
ascending (Optional, defaults to true): Boolean flag to determine the sort order (ascending or descending).
cmp_func (Optional, defaults to standard Avisynth comparison operators (>, <)): The name of a custom user
function for comparing array elements.
cmp_args (Optional, defaults to "": Additional arguments (as a string) for the custom compare function.
avg_func (Optional, defaults to Average()): The name of a custom user function for averaging array elements.
avg_args: (Optional, defaults to "": Additional arguments (as a string) for the custom average function.

Notes and conditions on arguments relations:


1] Both cmp_func and avg_func must accept two array elements (of the appropriate type) as their first two
arguments in their argument list.
2] cmp_func must return one of the -1, 0, 1 when elm1 < elm2, elm1 == elm2, elm1 > elm2, respectively.

Examples:
a1 = ArrayCreate(1, 3, 5, 8, 12, -4, 0, 2)
a2 = a1.ArraySort()
# a2 == "-4, 0, 1, 2, 3, 5, 8, 12"
a3 = a1.ArraySort(false)
# a3 == "12, 8, 5, 3, 2, 1, 0, -4"
The base package
The base package contains modules that provide basic extensions to Avisynth script language as well as basic
components of other AVSLib modules.

Required packages
None

Modules
Name Description
constants This module provides global constants commonly used in Avisynth scripts.

This module provides functions, constants and global variables for the
conversion
implementation of conversions between standard Avisynth types.

This module provides functions, constants and global variables for the
core
implementation of basic (core) capabilities of AVSLib.

This module provides functions, constants and global variables for the
version
implementation of AVSLib version reporting capabilities.
The base :: constants module
The base :: constants module provides global constants commonly used in Avisynth scripts.

Required modules
None

Functions
None

Constants
Name Description
TAB The tab character (string constant).

CRLF The CR/LF line break pair (string constant).

FRATE_NTSC NTSC video framerate

FRATE_PAL PAL video framerate

FRATE_FILM Film (movie) framerate

FRATE_IMAX IMax film framerate

ASRAT_TV Television aspect ratio

ASRAT_TVWIDE Wide TV aspect ratio

ASRAT_ANIM Animation film aspect ratio

ASRAT_ACFLAT1 Academy Flat 1 aspect ratio

ASRAT_ACFLAT2 Academy Flat 2 aspect ratio

ASRAT_SCOPE Cinescope aspect ratio

WSIZE_NTSC NTSC video pixel width

HSIZE_NTSC NTSC video pixel height

OSIZE_NTSC NTSC video pixel height including overscan lines

WSIZE_PAL PAL video pixel width

HSIZE_PAL PAL video pixel height

OSIZE_PAL PAL video pixel height including overscan lines


Name Description
Minimum RGB clip's width (progressive & interlaced). Also the multiple-of base
CS_MINW_RGB
of valid RGB clips' widths.

Minimum YUY2 clip's width (progressive & interlaced). Also the multiple-of base
CS_MINW_YUY2
of valid YUY2 clips' widths.

Minimum YV12 clip's width (progressive & interlaced). Also the multiple-of base
CS_MINW_YV12
of valid YV12 clips' widths.

Minimum progressive RGB clip's height. Also the multiple-of base of valid
CS_MINH_RGB
progressive RGB clips' heights.

Minimum progressive YUY2 clip's height. Also the multiple-of base of valid
CS_MINH_YUY2
progressive YUY2 clips' heights.

Minimum progressive YV12 clip's height. Also the multiple-of base of valid
CS_MINH_YV12
progressive YV12 clips' heights.

Minimum interlaced RGB clip's height. Also the multiple-of base of valid
CS_MINI_RGB
interlaced RGB clips' heights.

Minimum interlaced YUY2 clip's height. Also the multiple-of base of valid
CS_MINI_YUY2
interlaced YUY2 clips' heights.

Minimum interlaced YV12 clip's height. Also the multiple-of base of valid
CS_MINI_YV12
interlaced YV12 clips' heights.

Variables
None
The base :: conversion module
The base :: conversion module provides functions, constants and global variables for the implementation of
conversions between standard Avisynth types.

Required modules
base :: core

Functions
Name Description
Converts any variable to a bool type variable. The conversion
CBool()
follows the rules...

Converts any variable to a clip type variable. The conversion


CClip()
follows ...

Converts any variable to a float type variable. The conversion


CFloat()
follows the rules...

Converts any variable to an int type variable. The conversion


CInt()
follows the rules...

Converts any variable to a string type variable. The function


CString()
behaves like the...

Constants
None

Variables
None
CBool
Module: base :: conversion
Definition:
CBool(val "x", bool "force")

Description:
Converts any variable to a bool type variable. The conversion follows the rules of the table below:
Result
Type of x
true false
clip x.Framecount > 0 x.Framecount == 0
float x <> 0.0 x == 0.0
int x>0 x == 0
bool x unchanged
string x <> "" x == ""

Arguments:
"x": The variable to convert.
"force" (Optional, defaults to false): If true and x is an fined variable (ie Defined(x) returns false) then the function
returns false. Else the function propagates the undefined variable to the caller, ie it returns an undefined value.

Examples:
i1 = 0
i2 = 12
f1 = 2.34
s1 = "test"
s2 = ""
u = Undef()
b1 = CBool(i1) # b1 == false
b2 = CBool(i2) # b2 == true
b3 = CBool(f1) # b3 == true
b4 = CBool(s1) # b4 == true
b5 = CBool(s2) # b5 == false
b6 = CBool(u) # Defined(b6) == false
b7 = CBool(u, true) # b7 == false
CClip
Module: base :: conversion
Definition:
CClip(val "x", bool "force")

Description:
Converts any variable to a clip type variable. The conversion follows the rules of the table below [1]:
Type of x Result
clip x unchanged
float x unchanged
int
bool
BlankClip().SubTitle(String(x))
string

Arguments:
"x": The variable to convert.
"force" (Optional, defaults to false): If true and x is an undefined variable (ie Defined(x) returns false) then the
function returns BlankClip(). Else the function propagates the undefined variable to the caller, ie it returns an
undefined value.

Examples:
f = 4.231
c = AVISource( ... )
s = "a test string"
c1 = CClip(f)
c2 = CClip(c) # c2 == c
c3 = CClip(s)
CFloat
Module: base :: conversion
Definition:
CFloat(val "x", bool "force")

Description:
Converts any variable to a float type variable. The conversion follows the rules of the table below:
Type of x Result
clip 0.0
float x unchanged
int Float(x)
bool if x == true 1.0, else 0.0
string Float(Value(x))

Arguments:
"x": The variable to convert.
"force" (Optional, defaults to false): If true and x is an undefined variable (ie Defined(x) returns false) then the
function returns 0.0. Else the function propagates the undefined variable to the caller, ie it returns an undefined
value.

Examples:
i = 12
b = true
s = "2.1"
f1 = CFloat(i) # f1 == 12.0
f2 = CFloat(b) # f2 == 1.0
f3 = CFloat(s) # f3 == 2.1
CInt
Module: base :: conversion
Definition:
CInt(val "x", bool "force")

Description:
Converts any variable to an int type variable. The conversion follows the rules of the table below:
Type of x Result
clip 0
float Int(x)
int x unchanged
bool if x == true 1, else 0
string Int(Value(x))

Arguments:
"x": The variable to convert.
"force" (Optional, defaults to false): If true and x is an undefined variable (ie Defined(x) returns false) then the
function returns 0.0. Else the function propagates the undefined variable to the caller, ie it returns an undefined
value.

Examples:
f = 12.62
b = false
s = "2.1"
i1 = CInt(f) # i1 == 12
i2 = CInt(b) # i2 == 0
i3 = CInt(s) # i3 == 2
CString
Module: base :: conversion
Definition:
CString(val "x", bool "force")

Description:
Converts any variable to a string type variable. The function behaves like the String() standard Avisynth function,
except that it can accept undefined variables also.

Arguments:
"x": The variable to convert.
"force" (Optional, defaults to false): If true and x is an undefined variable (ie Defined(x) returns false) then the
function returns "". Else the function propagates the undefined variable to the caller, ie it returns an undefined
value.

Examples:
f = 12.62
b = false
u = Undef()
s1 = CString(f) # s1 == "12.62"
s2 = CString(b) # i2 == "false"
s3 = CString(u) # Defined(s3) == false
s4 = CString(u, true) # s4 == ""
The base :: core module
The base :: core module provides functions, constants and global variables for the implementation of basic (core)
capabilities of AVSLib.

Required modules
None

Functions
Name Description
Conditionaly imports into the script one of two files based on the value of condition
ImportIf()
(file path_true...

IsCallable() Returns true if its argument can be called (ie it is a function)...

Returns a null (zero) value appropriate for the type of its argument (ie either a zero-
Null()
length clip, ...

Self() Returns its argument unchanged...

Throws an error (causing immediate termination of script execution), optionally


Throw()
showing a ...

Returns a distinct string value depending on the type of the variable passed as
Typename()
argument...

Undef() Returns an "undefined" value...

Returns a distinct integer value depending on the type of the variable passed as
VarType()
argument...

Constants
Name Description
MAX_INT Maximum positive int value supported by Avisynth

MIN_INT Minimum negative int value supported by Avisynth

Variables
None
ImportIf
Module: base :: core
Definition:
ImportIf(bool condition, string path_true, string "path_false")

Description:
Conditionaly imports into the script one of two files based on the value of condition (file path_true if condition ==
true, or file path_false if condition == false) [1].

Examples:
clp1 = AVISource(…)
clp2 = ImportIf(clp1.IsYUV, ""yuv_mask.avs"", ""rgb_mask.avs"")

IsCallable
Module: base :: core
Definition:
IsCallable(string func)

Description:
Returns true if its argument can be called (ie it is a function).
Be aware of possible side effects if the argument function modidies globals and can be called without arguments,
since it is actually called in order to find if it is callable.
The function is a modification - to allow its use as a "silent" (ie not throwing any error) callability test - of
stickboy's JDL_FunctionDefined, which on turn was based on the initial idea of mf for testing specific strings in
Avisynth error messages in order to extract useful information (see the related thread in doom9 forum for details).

Examples:
function user_func(int x) { return 2*x-5 }
b1 = IsCallable("user_func") # b1 == true
b2 = IsCallable("notexist_func") # b2 == false
Null
Module: base :: core
Definition:
Null(val "template")

Description:
Returns a null (zero) value appropriate for the type of its argument (ie either a zero-length clip, or zero, or false or
an empty string). If no argument is given it returns an undefined variable, as Undef does.

Examples:
c = AVISource(...)
d = 1.3
e = ...a condition... ? c : Null(c)
f = Null(d) # same as f = 0.0

Self
Module: base :: core
Definition:
Self(val x)

Description:
Returns its argument unchanged. [1]

Examples:
x = 2.3
y = Self(x) # y == 2.3
s = "a test string"
z = Self(s) # y == "a test string"

Throw
Module: base :: core
Definition:
Throw(string "error_msg")

Description:
Throws an error (causing immediate termination of script execution), optionally showing a custom error message.

Examples:
b = ...something...
# the line below will stop script if b > 10
t = b > 10 ? Throw("this is an error") : 5
Typename
Module: base :: core
Definition:
Typename(val x)

Description:
Returns a distinct string value depending on the type of the variable passed as argument (the standard Avisynth
type's name, in lowercase).

Examples:
v0 = VarType(Undef()) # v0 == "undefined"
v1 = Typename(BlankClip()) # v1 == "clip"
v2 = Typename(3) # v2 == "int"
v3 = Typename(2.35) # v3 == "float"
v4 = Typename(true) # v4 == "bool"
v5 = Typename("this is a string") # v5 == "string"

Undef
Module: base :: core
Definition:
Undef()

Description:
Returns an "undefined" value.
Intended usage is to set an already-defined variable to an "undefined" state.
Initially a reverb of stickboy's Undefined function to accommodate the different coding conventions used in
AVSLib, now (from AVSLib version 1.1.0) the function has a new implementation without "private" arguments.
This will also result in a different error text if one ever tries to pass an argument to it.

Examples:
v = Undef()
b = Defined(v) # b == false
VarType
Module: base :: core
Definition:
VarType(val x)

Description:
Returns a distinct integer value depending on the type of the variable passed as argument (0 for undefined
variables, 1 for clip, 2 for int, 3 for float, 4 for bool, 5 for string).
Useful for branching code execution based on argument's type.

Examples:
v0 = VarType(Undef()) # v0 == 0
v1 = VarType(BlankClip()) # v1 == 1
v2 = VarType(3) # v2 == 2
v3 = VarType(2.35) # v3 == 3
v4 = VarType(true) # v4 == 4
v5 = VarType("this is a string") # v5 == 5
The base :: version module
The base :: version module provides functions, constants and global variables for the implementation of AVSLib
version reporting capabilities.

Required modules
None

Functions
Name Description
AvslibVersion() Returns a clip with AVSLib's version and copyright information...

AvslibVersionNumber() Returns the AVSLib's version number as a float...

AvslibVersionString() Returns a string with the AVSLib's version number...

Constants
Name Description
AVISYNTH_NUM_MAJOR The first digit in Avisynth's version number, as an int.

AVISYNTH_NUM_MINOR The second digit in Avisynth's version number, as an int.

AVISYNTH_NUM_PATCH The third digit in Avisynth's version number, as an int.

AVSLIB_NUM_MAJOR The first digit in AVSLib's version number, as an int.

AVSLIB_NUM_MINOR The second digit in AVSLib's version number, as an int.

AVSLIB_NUM_PATCH The third digit in AVSLib's version number, as an int.

Variables
None
AvslibVersion
Module: base :: version
Definition:
AVSLibVersion()

Description:
Returns a clip with AVSLib's version and copyright information.

Examples:
AVSLibVersion()

AvslibVersionNumber
Module: base :: version
Definition:
AVSLibVersionNumber()

Description:
Returns the AVSLib's version number as a float.

Examples:
f = AVSLibVersionNumber()
flag = f > 1.0 ? true : false

AvslibVersionString
Module: base :: version
Definition:
AVSLibVersionString()

Description:
Returns a string with the AVSLib's version number.

Examples:
BlankClip().SubTitle(AVSLibVersionString())
The bool package
The bool package contains modules that extend standard Avisynth operations on variables of boolean type.

Required packages
The bool package requires modules from the following packages (see the specific modules' documentation for
actual dependencies): base.

Modules
Name Description
This module provides functions, constants and global variables for the implementation of
core
basic operations on boolean variables.
The bool :: core module
The bool :: core module provides functions, constants and global variables for the implementation of basic
operations on boolean variables.

Required modules
base :: core

Functions
Name Description
And() Returns the result of the AND of its arguments...

And2() Returns the result of the AND of its arguments...

Not() Returns the result of the NOT of its argument...

Or() Returns the result of the OR of its arguments...

Or2() Returns the result of the OR of its arguments...

Xor2() Returns the result of the XOR (exclusive or) of its arguments...

Constants
None

Variables
None
And
Module: bool :: core
Definition:
And(val x1, val "x2", val "x3", val "x4", ... , val "x20")

Description:
Returns the result of the AND of its arguments. [1]
Possible usage includes combination of multiple tests in Assert() statements, bitwise flags testing, etc.

Examples:
d = And(true, true, false) # d == false
a = And(1 < 2, 2 < 3, d == false) # a == true
[1]: Thefunction can handle up to 20 arguments. This number is chosen as a good balance between usability and
speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array
package.

And2
Module: bool :: core
Definition:
And2(val x1, val x2)

Description:
Returns the result of the AND of its arguments. [1]

Examples:
d = And2(w > t, w == 4)
#d == true since both arguments are true bool expressions
[1]: Thefunction is provided as a building block of more complex functions, particularly for operations on arrays.
See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum
functions.
Not
Module: bool :: core
Definition:
Not(val x)

Description:
Returns the result of the NOT of its argument. [1]

Examples:
b = true
c = Not(b) # c == false
[1]: Thefunction is provided as a building block of more complex functions, particularly for operations on arrays.
See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum
functions.

Or
Module: bool :: core
Definition:
Or(val x1, val "x2", val "x3", val "x4", ... , val "x20")

Description:
Returns the result of the OR of its arguments. [1]
Possible usage includes combination of multiple tests in Assert() statements, combination of bitwise flags in one
value, etc.

Examples:
b1 = Or(true, true, false, false) # b1 == true
b2 = Or(1 == 0, 2 < 1, 3 == Factorial(2)) # b2 == false
b3 = Or(b1, b1 == b2, false) # b3 == true
[1]: Thefunction can handle up to 20 arguments. This number is chosen as a good balance between usability and
speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array
package.
Or2
Module: bool :: core
Definition:
Or2(val x1, val x2)

Description:
Returns the result of the OR of its arguments. [1]

Examples:
b1 = Or2(true,true) # b1 == true
b2 = Or2(true,false) # b2 == true
b3 = Or2(false,true) # b3 == true
b4 = Or2(false,false) # b4 == false
[1]: Thefunction is provided as a building block of more complex functions, particularly for operations on arrays.
See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum
functions.

Xor2
Module: bool :: core
Definition:
Xor2(val x1, val x2)
Description:
Returns the result of the XOR (exclusive or) of its arguments. [1]

Examples:
b1 = Xor2(true,true) # b1 == false
b2 = Xor2(true,false) # b2 == true
b3 = Xor2(false,true) # b3 == true
b4 = Xor2(false,false) # b4 == false
[1]: Thefunction is provided as a building block of more complex functions, particularly for operations on arrays.
See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum
functions.
The clip package
The clip package contains modules that extend standard Avisynth operations on variables of clip type.

Required packages
The clip package requires modules from the following packages (see the specific modules' documentation for
actual dependencies): base, numeric, string, array.

Modules
Name Description
This module provides functions, constants and global variables for performing specific to clip
arrays
arrays operations.

This module provides functions, constants and global variables for performing basic operations
core
related to clips.
The clip :: arrays module
The clip :: arrays module provides functions, constants and global variables for performing specific to clip arrays
operations.

Required modules
base :: conversion, numeric :: core, string :: core, array :: core, array :: operators,
array :: transforms, array :: properties

Functions
Name Description
JointFPS() Returns the most common (ie with maximum occurence) framerate of a clip array...

JointPixelType() Returns the most common (ie with maximum occurence) pixel type of a clip array...

Constants
None

Variables
None
JointFPS
Module: clip :: arrays
Definition:
JointFPS(string clips)

Description:
Returns the most common (ie with maximum occurence) framerate of a clip array.
Between framerates with the same occurence, the function favors those with the smaller value; for example if an
array of 5 clips has fps [24,24,25,30,30] the function will return 24.

Examples:
# assuming ar is a clip array with 2 24-fps clips, 3 29.97-fps clip
# and 2 59.94-fps clips (7 clips in total):
fp = JointFPS(ar) # fp == 29.97 notes = $notes
JointPixelType
Module: clip :: arrays
Definition:
JointPixelType(string clips, bool "lowercase")

Description:
Returns the most common (ie with maximum occurence) pixel type of a clip array.
The function first honors total RGB/YUV occurence and then specific occurences of RGB/YUV subtypes.
In addition, when equal number of specific RGB/YUV subtypes is encountered, it favors YV12 over YUY2 and
RGB32 over RGB24, as well as YUY2 over RGB32 (when total RGB == total YUV).
Thus:
• If most clips are in RGB/YUV it returns the RGB/YUV pixel_type with the maximum occurence
(favoring YV12 and RGB32 when YUV/RGB subtypes' occurences are equal in number).
• If RGB clips == YUV clips, the specific subtype with the maximum occurence is returned (favoring by
this order: YV12 > YUY2 > RGB32 > RGB24 when all subtypes have the same occurence).

Arguments:
clips: The clip array.
lowercase (Optional, defaults to false): If true then the returned string is in lowercase.

Examples:
# assuming ar is a clip array with 3 RGB32, 1 RGB24
# and 3YUY2 clips (7 clips in total):
pt = JointPixelType(ar) # pt == "RGB32"
# assuming ar2 is a clip array with 3 RGB32, 1 RGB24
# 2 YV12 and 3 YUY2 clips (9 clips in total):
pt2 = JointPixelType(ar2) # pt2 == "YUY2"
# assuming ar3 is a clip array with 3 RGB32, 1 RGB24
# 3 YV12 and 1 YUY2 clips (8 clips in total):
pt3 = JointPixelType(ar3) # pt3 == "YV12"
# assuming ar4 is a clip array with 3 RGB32, 1 RGB24
# 2 YV12 and 2 YUY2 clips (8 clips in total):
pt4 = JointPixelType(ar4) # pt4 == "RGB32"
The clip :: core module
The clip :: core module provides functions, constants and global variables for performing basic operations related
to clips.

Required modules
numeric :: rounding, array :: core

Functions
Name Description
ColorSpace() Returns the colorspace of base as a string in the format used by Overlay()...

Returns true if pixel_type is a valid pixel type string (as it is used by many Avisynth
IsPixelType()
filters)...

MakeRGBColor() Returns an RGB color value, mapping appropriately the red, green, blue values (modul...

SafeHeight() Returns (by rounding) the closest to target_height safe height...

SafeWidth() Returns (by rounding) the closest to target_width safe width...

Returns an (R, G, B) integer array, mapping appropriately the rgb_color RGB color value
SplitRGBColor()
to red, green, blu...

Constants
None

Variables
None
ColorSpace
Module: clip :: core
Definition:
ColorSpace(clip base)

Description:
Returns the colorspace of base as a string in the format used by Overlay().
The return value is one of "RGB32", "RGB24", "YUY2" and "YV12"

Examples:
c = BlankClip().ConvertToYUY2()
s = c.ColorSpace() # s == "YUY2"

IsPixelType
Module: clip :: core

Definition:
IsPixelType(string pixel_type, bool "extended")

Description:
Returns true if pixel_type is a valid pixel type string (as it is used by many Avisynth filters).
If 'extended is true, the value "RGB" is also considered to be a valid pixel type (it is used by the
Show{Red/Green/Blue/Alpha} filters).

Examples:
b = IsPixelType("rgb32") # b == true c = IsPixelType("brown") # c == false

MakeRGBColor
Module: clip :: core

Definition:
MakeRGBColor(int red, int green, int blue)

Description:
Returns an RGB color value, mapping appropriately the red, green, blue values (modulo 256).
Examples:
c1 = MakeRGBColor(0, 0, 0) # c1 == black
c2 = MakeRGBColor(255, 255, 255) # c2 == white
c3 = MakeRGBColor(0, 0, 255) # c3 == blue
c4 = MakeRGBColor(256, 256, 512) # c4 == black
SafeHeight
Module: clip :: core

Definition:
SafeHeight(clip c, int target_height, bool "interlaced")

Description:
Returns (by rounding) the closest to target_height safe height.
Safe here means that the returned height is compatible with the format of clip c, taking into account interlacing-
imposed constrains (if interlaced is supplied and is true).

Examples:
c = AVISource(…).ConvertToYV12()
h = SafeHeight(c, 399)
# h == 400

SafeWidth
Module: clip :: core

Definition:
SafeWidth(clip c, int target_width)

Description:
Returns (by rounding) the closest to target_width safe width.
Safe here means that the returned width is compatible with the format of clip c [1].

Examples:
c = AVISource(…).ConvertToYV12()
w = SafeWidth(c, 397)
# w == 396
SplitRGBColor
Module: clip :: core

Definition:
SplitRGBColor(int rgb_color)

Description:
Returns an (R, G, B) integer array, mapping appropriately the rgb_color RGB color value to red, green, blue
values. The array values are in the range [0..255].
Notes and conditions on arguments relations:
rgb_color must be a valid RGB color value in the range [$000000..$FFFFFF] for the function to return correct
results.

Examples:
a1 = SplitRGBColor($ff00ff) # c1 == "255,0,255"
a2 = SplitRGBColor(MakeRGBColor(100,20,245))
# a2 == "100,20,245"
The debug package
The debug package contains modules that provide debuging facilities for script developers.

Required packages
The debug package requires modules from the following packages (see the specific modules' documentation for
actual dependencies): base, numeric, string, array.

Modules
Name Description
This module provides functions, constants and global variables for the implementation of basic
core
debuging operations such as breaking and printing diagnostic messages and variables' values.

This module provides functions, constants and global variables for the implementation of a
logging
conditional (based on current debug level) output of debuging information to log files.
The debug :: core module
The debug :: core module provides functions, constants and global variables for the implementation of basic
debuging operations such as breaking and printing diagnostic messages and variables' values.

Required modules
base :: core, array :: core, array :: operators, array :: slices

Functions
Name Description
ArrayPrint() Returns a clip with the values of the elements contained in array ...

ArrayPrintCP() Returns a clip with the values of the elements contained in array ...

Break() Stops script execution and displays the values of the variables passed as ...

BreakIf() Stops script execution if condition is true and displays the values ...

Print() Returns a clip with the values of the variables passed as arguments printed in ...

Constants
Name Description
PRN_WSIZE Width of the standard clip returned by Print(), ArrayPrint() and ArrayPrintCP() functions.

PRN_HSIZE Height of the standard clip returned by Print(), ArrayPrint() and ArrayPrintCP() functions.

Height of each (text) line of the standard clip returned by Print(), ArrayPrint() and
PRN_LSIZE
ArrayPrintCP() functions.

Number of lines contained in the standard clip returned by Print(), ArrayPrint() and
PRN_LINES
ArrayPrintCP() functions.

Variables
Name Description
A PRN_WSIZE x PRN_HSIZE, 1 sec clip that is used internally by the module's routines to print
PrintBase out information passed in by the caller. Note that by changing it, the output of Print(),
ArrayPrint() and ArrayPrintCP() functions will be affected.
ArrayPrint
Module: debug :: core
Definition:
ArrayPrint(string array)
Description:
Returns a clip with the values of the elements contained in array printed in separate lines (one line for each
element). [1]
Examples:
...
# check if script variables have correct values
# by embedding the following lines of code
ar = ArrayCreate(c1, c2, c3, offset_x, offset_y, eff)
return ArrayPrint(ar)
...
[1]: Note that if the string representation of a variable's value is very long it may be clipped.

ArrayPrintCP
Module: debug :: core
Definition:
ArrayPrintCP(string array, int "columns")

Description:
Returns a clip with the values of the elements contained in array printed in separate lines (one line for each
element). [1]
The function always return a clip with the height[2] of the clip stored in the PrintBase global variable.
If the number of elements is such that the output cannot be fit into one page, additional pages (ie frames) are
added to the clip.
In addition the elements may be printed in more than one columns per page, if columns is suplied and > 1.

Examples:
...
# check if a lot of script variables have correct values
# by embedding the following lines of code
ar = ArrayCreate(var1, var2, ..., var50)
return ArrayPrintCP(ar)
# if we wanted one 'page' then we could use
# return ArrayPrintCP(ar, 2)
...

[1]:Note that if the string representation of a variable's value is very long it may be clipped.
[2]:All debug printing functions return a clip with the width of the clip stored in the PrintBase global variable.
Break
Module: debug :: core

Definition:
Break(val "x01", val "x02", val "x03", val "x04", ... , val "x20")

Description:
Stops script execution and displays the values of the variables passed as arguments in the standard Avisynth dialog
box separated by "|" characters, after the string "User break:"

Examples:
v1 = 3.24
v2 = "test string"
v3 = true
...
Break(v1, v2, v3) # script stops here
...

BreakIf
Module: debug :: core

Definition:
BreakIf(bool condition, val "x01", val "x02", val "x03", val "x04", ... , val "x20")

Description:
Stops script execution if condition is true and displays the values of the variables passed as arguments (x01 - x20)
in the standard Avisynth dialog box separated by "|" characters, after the string "Conditional break:"

Examples:
apath = ...
c = AVISource(apath)
d = SomeFilter(c)
# script will stop only if d.Framecount < c.Framecount
BreakIf(d.Framecount < c.Framecount, d.Framecount, c.Framecount, apath)
...
Print
Module: debug :: core

Definition:
Print(val x01, val "x02", val "x03", val "x04", ... , val "x36")

Description:
Returns a clip with the values of the variables passed as arguments printed in separate lines (one line for each
variable).
Note that if the string representation of a variable's value is very long it may be clipped.

Examples:
c = BlankClip(length=12)
n = 24
f = 20.3456
b = 3*n - 15 <= 6*Log(f)
s = "hello world!"
return Print(c, n, f, b, s)
The debug :: logging module
The debug :: logging module provides functions, constants and global variables for the implementation of a
conditional (based on current debug level) output of debuging information to log files.

Required modules
numeric :: core, string :: core, string :: sprintf

Functions
Name Description
DebugLog()
Outputs debuging information in a log file ...

GetDebugFile()
Gets the filename of the current debug log file used by DebugLog()...

GetDebugMode()
Gets the value of the current debug mode (level). See DebugLog() for further details...

SetDebugFile()
Sets the filename of the current debug log file used by DebugLog()...

SetDebugMode()
Sets the value of the current debug mode (level). See DebugLog() for further details...
Constants
Name Description
SetDebugMode() related constant. Specifies that debug logging (from DebugLog()) will
DBG_NODEBUG not be performed.
This constant if passed directly to DebugLog() will cause the respective call to always
print information to the log file.
SetDebugMode() related constant. Specifies that user level 1 debug logging will be
DBG_LEVEL_1 performed.
Pass this constant to DebugLog() calls within your script which print the less detailed
level of information to the log file.
SetDebugMode() related constant. Specifies that user level 2 debug logging will be
DBG_LEVEL_2 performed.
Pass this constant to DebugLog() calls within your script which print basic to moderately
detailed level of information to the log file.
SetDebugMode() related constant. Specifies that user level 3 debug logging will be
DBG_LEVEL_3 performed.
Pass this constant to DebugLog() calls within your script which print moderately to
detailed level of information to the log file.
SetDebugMode() related constant. Specifies that user level 4 debug logging will be
performed.
DBG_LEVEL_4 Pass this constant to DebugLog() calls within your script which print a detailed level of
information to the log file.
You can define more user-level constants if desired by succesively adding 1, 2,3, ..., etc. to
this constant.
SetDebugMode() related constant. Avisynth libraries and plugins developers should derive
DBG_LIBRARY their library-specific debug constants by adding to this number an appropriate integer
offset (less than DBG_RESERVED - DBG_LIBRARY).

SetDebugMode() related constant. Debug level values equal or above DBG_RESERVED


are reserved for AVSLib's own use.
DBG_RESERVED
Note: The above scheme may change at the future to allow the user a more granular
control of what among different libraries should be logged.

Variables
None
DebugLog
Module: debug :: logging

Definition:
DebugLog(int debug_level, string format, val "p01", val "p02", val "p03", val "p04", ..., val "p50" )

Description:
Outputs debuging information in a log file [1].
If the supplied debug_level is >= current debug mode (level) the function uses StrPrint() to insert the values of
any defined variable arguments (p01, …, p50) into the string format and write it to the log file using
WriteFileEnd. Else the function does nothing.

Examples:
fmt = "Processed clip is %i frames long, %ix%i and %f fps."
c = AVISource(…)
SetDebugMode(2)

# this equals to a NOP (1 > 2)
DebugLog(1, fmt, c.FrameCount, c.Width, c.Height, c.Framerate)

# this will output to log file
DebugLog(2, fmt, c.FrameCount, c.Width, c.Height, c.Framerate)

[1]:Themain use of DebugLog is to trace the values of variables and function / filter arguments during code
execution by carefully placing calls to DebugLog inside script code.
Descriptive format strings (for example ones that name the function, the variable, etc) greatly help the
interpretation of log file contents.

GetDebugFile
Module: debug :: logging

Definition:
GetDebugFile()

Description:
Gets the filename of the current debug log file used by DebugLog().

Examples:
#TODO in a later version of AVSLib.
GetDebugMode
Module: debug :: logging

Definition:
GetDebugMode()

Description:
Gets the value of the current debug mode (level). See DebugLog() for further details.

Examples:
# TODO in a later version of AVSLib.

SetDebugFile
Module: debug :: logging

Definition:
SetDebugFile(string path)

Description:
Sets the filename of the current debug log file used by DebugLog().

Examples:
# TODO in a later version of AVSLib.

SetDebugMode
Module: debug :: logging

Definition:
SetDebugMode(int mode)

Description:
Sets the value of the current debug mode (level). See DebugLog() for further details.[1]
Examples:
# TODO in a later version of AVSLib.

[1]:AVSLib defines a number of constants for use with debug mode related functions. See the associated module's
documentation for details.
The numeric package
The numeric package contains modules that extend standard Avisynth operations on variables of numeric type
(ints and floats).

Required packages
The numeric package requires modules from the following packages (see the specific modules' documentation for
actual dependencies): base.

Modules
Name Description
This module provides functions, constants and global variables for performing basic operations
core
related to numeric types.
This module provides functions, constants and global variables for calculating points' coordinates
curves2d
on 2D curves.
This module extends the set of Avisynth numeric functions with new members (inverse and
functions
hyperbolic trigonometric functions, base-n exponentials and logarithms, etc.).
This module extends the set of Avisynth numeric functions with power series, polynomial and
powseries
factorial functions.
rounding This module extends the set of Avisynth numeric functions with base-n rounding functions.
statistics This module extends the set of Avisynth numeric functions with statistical functions.
The numeric :: core module
The numeric :: core module provides functions, constants and global variables for performing basic operations
related to numeric types.

Required modules
base :: core

Functions
Name Description
Clamp() Returns either x unchanged or one of the low_limit /...
Count() Returns the count of its arguments (ie the number of defined arguments in the ...
DegToRad() Returns the result of conversion of its degrees argument to radians...
Dif2() Returns the difference of its arguments...
Div2() Returns the quotient of the division of its arguments...
IsEven() Returns true if x is an even integer (a multiple of two),...
IsOdd() Returns true if x is an odd integer (not a multiple of two),...
Max() Returns the bigger of its (up to 20) arguments...
Max2() Returns the bigger of its (only two) arguments...
Min() Returns the smaller of its (up to 20) arguments...
Min2() Returns the smaller of (only two) its arguments...
Mod2() Returns the remainder of the division of its arguments...
Product() Returns the product of its (up to 20) arguments...
Product2() Returns the product of its (only two) arguments...
RadToDeg() Returns the result of conversion of its radians argument to degrees...
Sum() Returns the sum of its (up to 20) arguments...
Sum2() Returns the sum of its (only two) arguments...

Constants
None

Variables
None
Clamp
Module: numeric :: core
Definition:
Clamp(val x, val low_limit, val high_limit)
Description:
Returns either x unchanged or one of the low_limit / high_limit limiting values specified.
In other words it clamps x inside the interval [low_limit..high_limit].
Examples:
v = 2.8
w1 = Clamp(v, 2, 3) # w1 == 2.8
w2 = Clamp(v, 1, 2) # w2 == 2.0
w3 = Clamp(v, 3, 4) # w3 == 3.0

Count
Module: numeric :: core
Definition:
Count(val "x1", val "x2", val "x3", val "x4", ... , val "x20")
Description:
Returns the count of its arguments (ie the number of defined arguments in the function's argument list). [1]
Examples:
n = Count(1, 3, 5, 7) # n == 4
v1 = 3.24
v2 = Undef()
n = Count(1, 3, v1, v2) # n == 3

[1]: Thefunction can handle up to 20 arguments. This number is chosen as a good balance between usability and
speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array
package.

DegToRad
Module: numeric :: core
Definition:
DegToRad(float degrees)
Description:
Returns the result of conversion of its degrees argument to radians.
Examples:
r1 = DegToRad(180)
r2 = DegToRad(360)
# r1 == Pi and r2 == 2*Pi
Dif2
Module: numeric :: core
Definition:
Dif2(val x1, val x2)

Description:
Returns the difference of its arguments. [1]

Examples:
v = Dif2(5, 3) # v == 2
w = Dif2(-5, 3) # v == -8
[1]: Thefunction is provided as a building block of more complex functions, particularly for operations on arrays.
See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum
functions.

Div2
Module: numeric :: core
Definition:
Div2(val x1, val x2)

Description:
Returns the quotient of the division of its arguments. [1]

Examples:
v = Div2(5, 2) # v == 2 because both args are ints
w = Div2(5.0, 2) # v == 2.5 because 5.0 forces float division
[1]: Thefunction is provided as a building block of more complex functions, particularly for operations on arrays.
See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum
functions.

IsEven
Module: numeric :: core
Definition:
IsEven(int x)

Description:
Returns true if x is an even integer (a multiple of two), false otherwise.

Examples:
b1 = IsEven(3) # b1 == false
b2 = IsEven(16) # b2 == true
IsOdd
Module: numeric :: core
Definition:
IsOdd(int x)

Description:
Returns true if x is an odd integer (not a multiple of two), false otherwise.

Examples:
b1 = IsOdd(3) # b1 == true
b2 = Isodd(16) # b2 == false

Max
Module: numeric :: core
Definition:
Max(val x1, val "x2", val "x3", val "x4", ... , val "x20")

Description:
Returns the bigger of its arguments. [1]

Examples:
v = Max(1.1, 2.34, 3.05, -4, 0.9, 3) # v == 3.05
w = Max(-1.1, -2.34, 0, -4, -0.9) # w == 0
[1]: Thefunction can handle up to 20 arguments. This number is chosen as a good balance between usability and
speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array
package.

Max2
Module: numeric :: core
Definition:
Max2(val x1, val x2)
Description:
Returns the bigger of its arguments. [1]
Examples:
v = Max2(1.1, 2.34) # v == 2.34
w = Max2(-1.1, -2.34) # w == -1.1
[1]: Thefunction is provided as a building block of more complex functions, particularly for operations on arrays.
See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum
functions.
Min
Module: numeric :: core
Definition:
Min(val x1, val "x2", val "x3", val "x4", ... , val "x20")

Description:
Returns the smaller of its arguments. [1]

Examples:
v = Min(1.1, 2.34, 3.05, -4, 0.9, 3) # v == -4
w = Min(-1.1, -2.34, 0, -4, -0.9) # w == -4
[1]: Thefunction can handle up to 20 arguments. This number is chosen as a good balance between usability and
speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array
package.

Min2
Module: numeric :: core
Definition:
Min2(val x1, val x2)

Description:
Returns the smaller of its arguments. [1]
Examples:
v = Min2(1.1, 2.34) # v == 1.1
w = Min2(-1.1, -2.34) # w == -2.34
[1]: Thefunction is provided as a building block of more complex functions, particularly for operations on arrays.
See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum
functions.

Mod2
Module: numeric :: core
Definition:
Mod2(val x1, val x2)
Description:
Returns the remainder of the division of its arguments. [1]
Examples:
v = Mod2(7, 3) # v == 1
w = Mod2(1.1, 0.5) # w == 0.1
[1]: Thefunction is provided as a building block of more complex functions, particularly for operations on arrays.
See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum
functions.
Product
Module: numeric :: core
Definition:
Product(val x1, val "x2", val "x3", val "x4", ... , val "x20")
Description:
Returns the product of its arguments. [1]
Examples:
v = Product(3, 4, 6) # v is now 72
t = Product(0.5, 0.4, v) # t is now 14.4
z = Product(0.1, 0.2, v, t, t + v, t - v, 0.5)
# z is now 51,597.80
[1]: Thefunction can handle up to 20 arguments. This number is chosen as a good balance between usability and
speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array
package.

Product2
Module: numeric :: core
Definition:
Product2(val x1, val x2)
Description:
Returns the product of its arguments. [1]
Examples:
p = Product2(3, 4) # p is now 12
s = Product2(0.5, p) # s is now 6
[1]: Thefunction is provided as a building block of more complex functions, particularly for operations on arrays.
See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum
functions.

RadToDeg
Module: numeric :: core
Definition:
RadToDeg(float radians)
Description:
Returns the result of conversion of its radians argument to degrees.
Examples:
d1 = RadToDeg(Pi)
d2 = RadToDeg(2*Pi)
# d1 == 180 and d2 == 360
Sum
Module: numeric :: core
Definition:
Sum(val x1, val "x2", val "x3", val "x4", ... , val "x20")

Description:
Returns the sum of its arguments. [1]

Examples:
sm1 = Sum(2, 2, 3, 5, 1, 4) # sm1 == 17
sm2 = Sum(clip1, clip2, clip3) # clips can also be summed
sm3 = Sum("ab", "cde", "f") # sm3 == "abcdef"
[1]: Thefunction can handle up to 20 arguments. This number is chosen as a good balance between usability and
speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array
package.

Sum2
Module: numeric :: core
Definition:
Sum2(val x1, val x2)

Description:
Returns the sum of its arguments. [1]

Examples:
sm1 = Sum2(2, 2) # sm1 == 4
sm2 = Sum2(clip1, clip2) # clips can also be summed
sm3 = Sum2("ab", "cd") # sm3 == "abcd"
[1]: Thefunction is provided as a building block of more complex functions, particularly for operations on arrays.
See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum
functions.
The numeric :: curves2d module
The numeric :: curves2d module provides functions, constants and global variables for calculating points'
coordinates on 2D curves.

Required modules
None

Functions
Name Description
Circle() Returns the y-value of x so that the point (x,y) lies on a circle ...
Ellipsis() Returns the y-value of x so that the point (x,y) lies on an ellipsis ...
Hyperbola() Returns the y-value of x so that the point (x,y) lies on a hyperbola parallel to x axis ...
Line() Returns the y-value of x so that the point (x,y) lies on a line defined by its ...
Line1pt() Returns the y-value of x so that the point (x,y) lies on a line defined by its ...
Line2pt() Returns the y-value of x so that the point (x,y) lies on a line defined by two...
Parabola() Returns the y-value of x so that the point (x,y) lies on a parabola parallel to x axis, with ed...

Constants
None

Variables
None
Circle
Module: numeric :: curves2d
Definition:
Circle(float x, float radius, bool "up_part", float "xc", float "yc")

Description:
Returns the y-value of x so that the point (x,y) lies on a circle defined by its radius and its center (xc,yc).
If xc or yc are not provided they default to zero.
up_part determines whether the point will be on the upper or lower semi-circle. If up_part is true or omitted it
will on the upper semi-circle (ie >= yc), else on the lower (ie < yc).

Examples:
y_u = Circle(Pi()/4, 1) # y_u == Pi()/4
y_d = Circle(Pi()/4, 1, false) # y_d == -Pi()/4
y = Circle(5, 5, xc=5, yc=-5) # y == 0

Ellipsis
Module: numeric :: curves2d
Definition:
Ellipsis(float x, float a, float b, bool "up_part", float "xc", float "yc")
Description:
Returns the y-value of x so that the point (x,y) lies on an ellipsis defined by long axis half-length a, short axis half-
length b and its center (xc,yc).
If xc or yc are not provided they default to zero.
up_part determines whether the point will be on the upper or lower part of the curve. If up_part is true or omitted
it will on the upper part (ie >= yc), else on the lower (ie < yc).

Examples:
# TODO in a later version of AVSLib.
Hyperbola
Module: numeric :: curves2d
Definition:
Hyperbola(float x, float a, float b, bool "up_part", float "xc", float "yc")

Description:
Returns the y-value of x so that the point (x,y) lies on a hyperbola parallel to x axis defined by long axis half-
length a, short axis half-length b and its center (xc,yc).
If xc or yc are not provided they default to zero.
up_part determines whether the point will be on the upper or lower part of the curve. If up_part is true or omitted
it will on the upper part (ie >= yc), else on the lower (ie < yc).
Notes and conditions on arguments relations:
1) If x >= xc + a the function returns the y-value that corresponds to a point on the right branch of the
hyperbola.
2) If x <= xc - a the function returns the y-value that corresponds to a point on the left branch of the
hyperbola.
3) If x does not satisfy the above two conditions (does not correspond to a point in any branch, the function
throws an error.
4) Exchange x,y to get a hyperbola with axis parallel to y axis.

Examples:
# TODO in a later version of AVSLib.

Line
Module: numeric :: curves2d
Definition:
Line(float x, float slope, float intercept)

Description:
Returns the y-value of x so that the point (x,y) lies on a line defined by its slope and intercept.
Examples:
y1 = Line(2, 1, 0) # y = 1x + 0 = x == 2
y2 = Line(2, 0.5, 4) # y = 0.5x + 4 == 5
Line1pt
Module: numeric :: curves2d
Definition:
Line1pt(float x, float x1, float y1, float slope)

Description:
Returns the y-value of x so that the point (x,y) lies on a line defined by its slope and a given point (x1,y1).

Examples:
y1 = Line1pt(2, 0, 1, 0.5) # y = 0.5x + 1 == 2
y2 = Line1pt(0, 1, 1, -1) # y = -x + 2 == 2

Line2pt
Module: numeric :: curves2d
Definition:
Line2pt(float x, float x1, float y1, float x2, float y2)

Description:
Returns the y-value of x so that the point (x,y) lies on a line defined by two given points (x1,y1) and (x2,y2).

Examples:
y1 = Line2pt(2, 0, 1, 4, 3) # y = 0.5x + 1 == 2
y2 = Line2pt(0, 1, 1, 3, -1) # y = -x + 2 == 2

Parabola
Module: numeric :: curves2d
Definition:
Parabola(float x, float a, bool "up_part", float "xc", float "yc")

Description:
Returns the y-value of x so that the point (x,y) lies on a parabola parallel to x axis, with edge located at distance a
from its focus and its center located at (xc,yc).
If xc or yc are not provided they default to zero.
up_part determines whether the point will be on the upper or lower part of the curve. If up_part is true or omitted
it will on the upper part (ie >= yc), else on the lower (ie < yc).
Notes and conditions on arguments relations:
1) If x >= xc the function returns the y-value that corresponds to a parabola opening towards the right x
semi-axis; else the y-value that corresponds to a parabola opening towards the left x semi-axis.
2) Exchange x,y to get a hyperbola with axis parallel to y axis.
Examples:
# TODO in a later version of AVSLib.
The numeric :: functions module
The numeric :: functions module extends the set of Avisynth numeric functions with new members (inverse and
hyperbolic trigonometric functions, base-n exponentials and logarithms, etc.).

Required modules
numeric :: core

Functions
Name Description
ArcCos() Returns the inverse cosine of its argument...
ArcCosh() Returns the inverse hyperbolic cosine of its argument...
ArcCot() Returns the inverse cotangent of its argument...
ArcCoth() Returns the inverse hyperbolic cotangent of its argument...
ArcSin() Returns the inverse sine of its argument...
ArcSinh() Returns the inverse hyperbolic sine of its argument...
ArcTan() Returns the inverse tangent of its argument...
ArcTanh() Returns the inverse hyperbolic tangent of its argument...
Cosh() Returns the hyperbolic cosine of its argument...
Cot() Returns the cotangent of its argument...
Coth() Returns the hyperbolic cotangent of its argument...
Exp10() Returns the base-10 exponent of x (ie 10x)...
ExpBs() Returns the base-base exponent of x (ie (base)x)...
Log10() Returns the base-10 logarithm of x (ie Log10(x))...

LogBs() Returns the base-base logarithm of x (ie logbase(x))...

Sinh() Returns the hyperbolic sine of its argument...


Tan() Returns the tangent of its argument...
Tanh() Returns the hyperbolic tangent of its argument...

Constants
None

Variables
None
ArcCos
Module: numeric :: functions
Definition:
ArcCos(float x)

Description:
Returns the inverse cosine of its argument.

Examples:
v = ArcCos(0.5403) # v == 1.0000
v = ArcCos(Pi/4) # v == 0.6675

ArcCosh
Module: numeric :: functions
Definition:
ArcCosh(float x)

Description:
Returns the inverse hyperbolic cosine of its argument.

Examples:
v = ArcCosh(1.5431) # v == 1.0000
v = ArcCosh(3.7622) # v == 2,0000

ArcCot
Module: numeric :: functions
Definition:
ArcCot(float x)

Description:
Returns the inverse cotangent of its argument.

Examples:
v = ArcCot(0.6421) # v == 1.0000
v = ArcCot(-0.4577) # v == 2.000
ArcCot
Module: numeric :: functions
Definition:
ArcCot(float x)

Description:
Returns the inverse cotangent of its argument.

Examples:
v = ArcCot(0.6421) # v == 1.0000
v = ArcCot(-0.4577) # v == 2.000

ArcSin
Module: numeric :: functions
Definition:
ArcSin(float x)

Description:
Returns the inverse sine of its argument.

Examples:
v = ArcSin(0.84147) # v == 1.0000
v = ArcSin(0.5) # v == 0.5236

ArcSinh
Module: numeric :: functions
Definition:
ArcSinh(float x)

Description:
Returns the inverse hyperbolic sine of its argument.

Examples:
v = ArcSinh(1.1752) # v == 1.000
v = ArcSinh(3.6269) # v == 2.0000
ArcTan
Module: numeric :: functions
Definition:
ArcTan(float x)

Description:
Returns the inverse tangent of its argument.

Examples:
v = ArcTan(1.5574) # v == 1.0000
v = ArcTan(2) # v == 1.1071

ArcTanh
Module: numeric :: functions
Definition:
ArcTanh(float x)

Description:
Returns the inverse hyperbolic tangent of its argument.

Examples:
v = ArcTanh(0.7616) # v == 1.0000
v = ArcTanh(Pi/4) # v == 1.0593

Cosh
Module: numeric :: functions
Definition:
Cosh(float x)

Description:
Returns the hyperbolic cosine of its argument.

Examples:
v = Cosh(1) # v == 1.5431
v = Cosh(2) # v == 3.7622
Cot
Module: numeric :: functions
Definition:
Cot(float x)

Description:
Returns the cotangent of its argument.

Examples:
v = Cot(1) # v == 0.6421
v = Cot(2) # v == -0.4577

Coth
Module: numeric :: functions
Definition:
Coth(float x)

Description:
Returns the hyperbolic cotangent of its argument.

Examples:
v = Coth(1) # v == 1.3130
v = Coth(2) # v == 1.0373

Exp10
Module: numeric :: functions
Definition:
Exp10(float x)

Description:
Returns the base-10 exponent of x (ie 10x).

Examples:
e1 = Exp10(1) # e1 == 10
e2 = Exp10(3) # e2 == 1000
ExpBs
Module: numeric :: functions
Definition:
ExpBs(float x, float base)

Description:
Returns the base-base exponent of x (ie (base)x). The base argument can take any value allowed by Pow function.

Examples:
e1 = ExpBs(1, 2.5) # e1 == 2.5
e2 = ExpBs(2, 3) # e2 == 9

Log10
Module: numeric :: functions
Definition:
Log10(float x)

Description:
Returns the base-10 logarithm of x (ie Log10(x)).

Examples:
l1 = Log10(10) # l1 == 1
l2 = Log10(1000) # l2 == 3

LogBs
Module: numeric :: functions
Definition:
LogBs(float x, float base)

Description:
Returns the base-base logarithm of x (ie logbase(x)). The base argument can take any allowed real value.

Examples:
l1 = LogBs(2.5, 2.5) # l1 == 1
l2 = LogBs(9, 3) # l2 == 2
Sinh
Module: numeric :: functions
Definition:
Sinh(float x)

Description:
Returns the hyperbolic sine of its argument.

Examples:
v = Sinh(1) # v == 1.1752
v = Sinh(2) # v == 3.6269

Tan
Module: numeric :: functions
Definition:
Tan(float x)

Description:
Returns the tangent of its argument.

Examples:
v = Tan(1) # v == 1.5574
v = Tan(2) # v == -2.1850
The numeric :: powseries module
The numeric :: powseries module extends the set of Avisynth numeric functions with power series, polynomial
and factorial functions.

Required modules
None

Functions
Name Description
Factorial() Returns the factorial of x (ie x!)...
Polynomial() Returns an arbitrary polynomial of x...
PowSeries() Returns an arbitrary power series of x...

Constants
None

Variables
None
Factorial
Module: numeric :: powseries
Definition:
Factorial(int x)

Description:
Returns the factorial of x (ie x!).

Examples:
n1 = Factorial(3) # n1 == 6
n2 = Factorial(5) # n2 == 120

Polynomial
Module: numeric :: powseries
Definition:
Polynomial(float x, string coef_func, int start_index, int end_index, int "increment", string "coef_args")

Description:
Returns an arbitrary polynomial of x.
The polynomial is generated by summing the terms coef_func(index, coef_args) * Pow(x, index)) for all indexes
in the range [start_index .. end_index), ie end_index is not included.
The function is a special case of the more general PowSeries function, where the power_func argument is the Self
function.
See PowSeries for an explanation of the arguments.

Examples:
# Calculate the polynomial (2 + bn)*x2n starting from n=0 and taking 10 terms for
value of x = 5.4 and b = 2.3
function mycoef(int i, float b) { return 2 + b * Int(i / 2) }
# Since i increases at step of 2, i/2 will increase at steps of 1
p1 = Polynomial(5.4, "mycoef", 0, 20, 2, String(2.3))
PowSeries
Module: numeric :: powseries
Definition:
PowSeries(float x, string coef_func, string power_func, int start_index,
int end_index, int "increment", string "coef_args", string "power_args")
Description:
Returns an arbitrary power series of x.
The power series is generated by summing the terms coef_func(index, coef_args) * Pow(x, power_func(index,
power_args)) for all indexes in the range [start_index .. end_index), ie end_index is NOT included.
coef_func and power_func user-functions must accept an integer (the index of the series term) as their first
argument. Optionally, they can accept other arguments, which can be passed as strings (containing the
intermediate commas) with the "coef_args" and "power_args" arguments.

Arguments:
x: The value of which the power series will be calculated.
coef_func: The name of the function that produces the coefficients of the series. coef_args argument.
power_func: The name of the function that produces the powers of the series.
start_index: The index of the first term of the series.
end_index: The first index after the end of the series (that is, no term will be generated for that index).
"increment" (Optional, defaults to 1): The increment between successive indexes of the series.
"coef_args" (Optional, defaults to ""): Additional arguments to pass to the coef_func function.
"power_args" (Optional, defaults to ""):

Notes and conditions on arguments relations:


1. start_index must be <= end_index. In the special case where these two are equal the function returns
zero.
2. If coef_args or power_args contain string arguments, the later must be surrounded with double quotes
before entering them into the arguments. Use StrQuote for this purpose.
3. Since coef_func and power_func are the first constituents of the constructed string for Eval() you can
perform simple operations with constants and globals inside those strings, such as multiplication and
addition (eg. set coef_func to "2 + funcname").
Examples:
# Calculate the power series (2n/n!)*x(2n+1)
# for n=0 to 19 and value of x = 1.4
function mycoef(int i) { return Pow(2, i) / Factorial(i) }
function mypow(int i) { return 2 * i + 1 }
f1 = PowSeries(1.4, "mycoef", "mypow", 0, 20)

# Calculate the power series (2/n!)*x2n for n=4 to 16,


# with step 2 and value of x = 0.5
f2 = PowSeries(0.5, "2 / Factorial", "2 * Self", 4, 18, 2)

# Calculate the power series [Sin(n*pi()*x/a)/(2n)]*x(2n+1)/b


# for n=-10 to 10 (included) and value of
# x = 0.75 with a = 10 and b = Pi()
function mycoef(int i, float x, float a) {
return Sin(i*Pi()*x/a) / Pow(2, i)
}
function mypow(int i, float b) { return (2 * i + 1)/b }
f3 = PowSeries(0.75, "mycoef", "mypow", -10, 11, 1, "0.75, 10", "Pi()")
The numeric :: rounding module
The numeric :: rounding module extends the set of Avisynth numeric functions with base-n rounding functions.

Required modules
numeric :: core

Functions
Name Description
CeilBs() An extension to the Ceil standard Avisynth function for arbitrary (integer) base base...
FloorBs() An extension to the Floor standard Avisynth function for arbitrary (integer) base base...
FRound() Returns x rounded to decimals accuracy, taking care not to overflow during the intermediate cal...
IntBs() An extension to the Int standard Avisynth function for arbitrary (integer) base base...
RoundBs() An extension to the Round standard Avisynth function for arbitrary (integer) base base...
RoundEven() Returns the closest even integer to its argument...
RoundOdd() Returns the closest odd integer to its argument...

Constants
None

Variables
None
CeilBs
Module: numeric :: rounding
Definition:
CeilBs(float x, int "base")

Description:
An extension to the Ceil standard Avisynth function for arbitrary (integer) base base.[1] It returns the base-base
ceiling of x (ie the smallest integral multiple of base that is greater or equal to x).

Examples:
f1 = CeilBs(3.3, 2) # f1 == 4.0
f2 = CeilBs(7.3, 3) # f2 == 9.0
f3 = CeilBs(7.3, 1) # f3 == 8.0
[1]: Like the Ceil standard Avisynth function, CeilBs is non-symmetrical around the axis origin and periodic.
Consequently, the following equalities hold:
Ceil(x) = k, x in (k-1..k] for every k in Z
CeilBs(x, b) = kb, x in ((k-1)*b..k*b] for every k in Z

FloorBs
Module: numeric :: rounding
Definition:
FloorBs(float x, int "base")

Description:
An extension to the Floor standard Avisynth function for arbitrary (integer) base base.[1] It returns the base-base
floor of x (ie the largest integral multiple of base that is less or equal to x).

Examples:
f1 = FloorBs(3.3, 2) # f1 == 2.0
f2 = FloorBs(7.3, 3) # f2 == 6.0
f3 = FloorBs(7.3, 1) # f3 == 7.0
[1]:Like the Floor standard Avisynth function, FloorBs is non-symmetrical around the axis origin and periodic.
Consequently, the following equalities hold:
Floor(x) = k, x in [k..k+1) for every k in Z
FloorBs(x, b) = kb, x in [k*b..(k+1)*b) for every k in Z
FRound
Module: numeric :: rounding
Definition:
FRound(float x, int decimals)

Description:
Returns x rounded to decimals accuracy, taking care not to overflow during the intermediate calculations. The
result is a float number.
Note that when using negative decimals it is possible to zero the result if x < 0.5*Pow(10,-decimals).

Examples:
f1 = 2.345613
f2 = FRound(f1, 2) # f2 == 2.34
f3 = 2132.345
f4 = FRound(f3, -2) # f4 == 2100

IntBs
Module: numeric :: rounding
Definition:
IntBs(float x, int "base")

Description:
An extension to the Int standard Avisynth function for arbitrary (integer) base base.[1] It returns the base-base
truncated integer of x (ie the largest integral multiple of base with absolute value less or equal to Abs(x)).

Examples:
f1 = IntBs(3.3, 2) # f1 == 2.0
f2 = IntBs(7.3, 3) # f2 == 6.0
f3 = IntBs(7.3, 1) # f3 == 7.0
[1]:Like the Int standard Avisynth function, IntBs is symmetrical around the axis origin and not periodic.
Consequently, the following equalities hold:
Int(x) = Ceil(x), x < 0 | Floor(x), x > 0
IntBs(x, b) = CeilBs(x, b), x < 0 | FloorBs(x, b), x > 0
RoundBs
Module: numeric :: rounding
Definition:
RoundBs(float x, int "base")

Description:
An extension to the Round standard Avisynth function for arbitrary (integer) base base.[1] It returns the base-base
rounded integer of x (ie the integral multiple of base that has absolute difference from x less or equal to base/2).
[2]

Examples:
f1 = RoundBs(3.3, 2) # f1 == 4.0
f2 = RoundBs(7.3, 3) # f2 == 6.0
f3 = RoundBs(7.3, 1) # f3 == 7.0
[1]:Like the Round standard Avisynth function, RoundBs is symmetrical around the axis origin and not periodic.
Consequently, the following equalities hold:
Round(x) = k, x in (k-0.5..k+0.5) for every k in Z
RoundBs(x, b) = kb, x in ((k-0.5)*b..(k+0.5)*b) for every k in Z
[2]:The current implementation will overflow if x is near (ie less or equal than base) the maximum / minimum
integer limits. This limitation may be removed in a subsequent version.

RoundEven
Module: numeric :: rounding
Definition:
RoundEven(float x)

Description:
Returns the closest even integer to its argument.
Rounding is made such that the previous odd integer (even - 1) rounds to even, ie all values inside the interval
[even - 1..even + 1) round to even.

Examples:
re1 = RoundEven(7.0) # re1 == 8
re2 = RoundEven(8.999999) # re2 == 8
re3 = RoundEven(9.0) # re3 == 10
RoundOdd
Module: numeric :: rounding
Definition:
RoundOdd(float x)

Description:
Returns the closest odd integer to its argument.
Rounding is made such that the previous even integer (odd - 1) rounds to odd, ie all values inside the interval [odd
- 1..odd + 1) round to odd.

Examples:
ro1 = RoundOdd(6.0) # ro1 == 7
ro2 = RoundOdd(7.999999) # ro2 == 7
ro3 = RoundOdd(8.0) # ro3 == 9
The numeric :: statistics module
The numeric :: statistics module extends the set of Avisynth numeric functions with statistical functions.

Required modules
base :: core, numeric :: core

Functions
Name Description
Average() Returns the (statistical) average of its arguments...
StDev() Returns the (statistical) standard deviation of its arguments...
SumSquare() Returns the sum of squares of its arguments (ie each argument is raised to a power of 2 ...

Constants
None

Variables
None
Average
Module: numeric :: statistics
Definition:
Average(val x1, val "x2", val "x3", val "x4", ... , val "x20")
Description:
Returns the (statistical) average of its arguments. [1]
Examples:
avg = Average(6, 5, 7, 9, 4, 8)
# avg == 6.5000, ie 39/6
[1]: Thefunction can handle up to 20 arguments. This number is chosen as a good balance between usability and
speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array
package.

StDev
Module: numeric :: statistics
Definition:
StDev(val x1, val "x2", val "x3", val "x4", ... , val "x20")
Description:
Returns the (statistical) standard deviation of its arguments. [1]
Examples:
sd1 = StDev(2, 2, 3, 5, 1, 4) # sd1 == 1.4720
sd2 = StDev(3, 1, 3, 5, 2, 4) # sd1 == 1.4142
[1]: Thefunction can handle up to 20 arguments. This number is chosen as a good balance between usability and
speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array
package.

SumSquare
Module: numeric :: statistics
Definition:
SumSquare(val x1, val "x2", val "x3", val "x4", ... , val "x20")
Description:
Returns the sum of squares of its arguments (ie each argument is raised to a power of 2 before contributing to the
sum). [1]
Examples:
ss1 = SumSquare(2, 2, 3, 5, 1, 4) # ss1 == 59
ss2 = SumSquare(3, 1, 3, 5, 2, 4) # ss2 == 64
[1]: Thefunction can handle up to 20 arguments. This number is chosen as a good balance between usability and
speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array
package.
The string package
The string package contains modules that extend standard Avisynth operations on variables of string type.

Required packages
The string package requires modules from the following packages (see the specific modules' documentation for
actual dependencies): base, numeric, array.

Modules
Name Description
This module provides functions, constants and global variables for performing basic operations
core
related to the string (and array) type.
This module provides functions, constants and global variables for performing extended string
search
searching and replacement operations.
sprintf This module provides StrPrint, a string formatting function with sprintf-like interface.
The string :: core module
The string :: core module provides functions, constants and global variables for performing basic operations
related to the string (and array) type.

Required modules
base :: core

Functions
Name Description
IsQuoted() Returns true if x starts and ends with a " character...
QuoteNoexpr() Returns its argument string either quoted if it fails to evaluate (and thus it is not ...
Compares strings s1 and s2 and returns -1,0,1 if s1 < s2, s1 == s2, s1 > s2,
StrCompare()
respectively...
StrFill() Returns a string consisting of count repetitions of s...
A replacement of LeftStr standard Avisynth function. For Avisynth versions up to 2.55
StrLeft()
offers the ability ...
A replacement of MidStr standard Avisynth function. For Avisynth versions up to 2.55
StrMid()
offers the ability to...
StrQuote() Returns its argument with one " character added at the begining and at the end...
A replacement of RightStr standard Avisynth function. For Avisynth versions up to 2.55
StrRight()
offers the ability ...
StrUnquote() Returns its argument with one " character at the begining and one at the end ...
ZStrip() Returns fpnum stripped from leading and trailing zeros if fpnum ...

Constants
Name Description
The active character set. Used for case-sensitive search and replace by the string :: search
CHAR_SET
module's functions.

Variables
None
IsQuoted
Module: string :: core
Definition:
IsQuoted(string x)

Description:
Returns true if x starts and ends with a " character.
Note that for zero-length and one-length strings it returns false.

Examples:
s = StrQuote("test string")
b1 = IsQuoted(s) # b1 == true
t = "test string"
b2 = IsQuoted(t) # b2 == false
u = Chr(34) # a single " character
b3 = IsQuoted(u) # b3 == false

QuoteNoexpr
Module: string :: core
Definition:
QuoteNoexpr(string x)

Description:
Returns its argument string either quoted if it fails to evaluate (and thus it is not a valid expression or global
identifier's name) or unchanged if it succeeds to evaluate.
Its intended usage is constructing proper strings for passing to Eval() but be aware of possible side effects if its
argument contains an exression or a function that assigns to globals and not just a variable name.
This function is used by the array package.

Examples:
global nb_exp = 2
s = QuoteNoexpr("nb_exp") # s == 'nb_exp'
t = QuoteNoexpr("nbnoexp") # t == '"nbnoexp"'
StrCompare
Module: string :: core
Definition:
StrCompare(string s1, string s2, bool "ignorecase", string "comparefunc")

Description:
Compares strings s1 and s2 and returns -1,0,1 if s1 < s2, s1 == s2, s1 > s2, respectively.
Arguments:
ignorecase (Optional, defaults to True): Set it to false to perform a case-sensitive comparison.
comparefunc (Optional, defaults to standard Avisynth string comparison): A user-defined function that accepts up
to three arguments (the same as StrCompare, ie s1, s2 and (optionally) ignorecase and returns the same values as
StrCompare. Use it whenever a non-standard comparison has to be performed.

Examples:
v1 = StrCompare("aviSynth", "Avisynth") # v1 == 0
v2 = StrCompare("aviSynth", "Avisynth", true) # v2 == 1

StrFill
Module: string :: core
Definition:
StrFill(string s, int count, bool "strict")

Description:
Returns a string consisting of count repetitions of s.
If count == 0, a null string is returned.
The strict optional parameter when set to false makes the function to return a null string when a negative count
value is passed (the default behavior is to throw an error).

Examples:
s = StrFill("a", 12) # s == "aaaaaaaaaaaa"
t = StrFill("abc", 3) # t == "abcabcabc"
u = StrFill("abc", 0) # u == ""
# this will halt script with an error
v = StrFill("abc", -1)
# this will return a null string (same result as u, above)
v = StrFill("abc", -1, false)
StrLeft
Module: string :: core
Definition:
StrLeft(string s, int length)

Description:
A replacement of LeftStr standard Avisynth function. For Avisynth versions up to 2.55 offers the ability to handle
twice as large strings than the standard function; for later versions it has the same functionality.
Arguments:
The arguments are those of the associated standard Avisynth function.

Examples:
s1 = StrLeft("\avisynth", 5)
s2 = StrLeft("\avisynth", 3)
# s1 == "avisy", s2 == "avi"

StrMid
Module: string :: core
Definition:
StrMid(string s, int start, int "length")

Description:
A replacement of MidStr standard Avisynth function. For Avisynth versions up to 2.55 offers the ability to handle
twice as large strings than the standard function; for later versions it has the same functionality.
Arguments:
The arguments are those of the associated standard Avisynth function.

Examples:
s1 = StrMid("\avisynth", 1, 5)
s2 = StrMid("\avisynth", 6, 3)
# s1 == "avisy", s2 == "nth"
StrQuote
Module: string :: core
Definition:
StrQuote(string x)

Description:
Returns its argument with one " character added at the begining and at the end.

Examples:
s = "this is a string"
q = StrQuote(s) # q == '"this is a string"'

StrRight
Module: string :: core
Definition:
StrRight(string s, int length)

Description:
A replacement of RightStr standard Avisynth function. For Avisynth versions up to 2.55 offers the ability to handle
twice as large strings than the standard function; for later versions it has the same functionality.
Arguments:
The arguments are those of the associated standard Avisynth function.

Examples:
s1 = StrRight("\avisynth", 5)
s2 = StrRight("\avisynth", 3)
# s1 == "synth", s2 == "nth"
StrUnquote
Module: string :: core
Definition:
StrUnquote(string x)

Description:
Returns its argument with one " character at the begining and one at the end stripped (if both they exist). "
characters inside the string are left untouched.

Examples:
s = Chr(34) + "test string" + Chr(34)
l1 = StrLen(s) # l1 == 13, s == '"test string"'
t = StrUnquote(s)
l2 = StrLen(t) # l2 == 11, t == "test string"

ZStrip
Module: string :: core
Definition:
ZStrip(string fpnum)

Description:
Returns fpnum stripped from leading and trailing zeros if fpnum is a valid string representation of a number, else
fpnum unchanged.

Examples:
# strings 1 and 3 are valid numbers, 2 is not
s1 = ZStrip("2.304000") # s1 == "2.304"
s2 = ZStrip("24-10-003") # s2 == "24-10-003"
s3 = ZStrip("023.30240") # s3 == "23.3024"
The string :: search module
The string :: search module provides functions, constants and global variables for performing extended string
searching and replacement operations.

Required modules
string :: core, array :: core

Functions
Name Description
A generic substring search function that can return all positions of occurrence of sought inside
StrFind()
base...
A generic substring replacement function that can replace all occurrences of sought inside
StrReplace()
base...

Constants
None

Variables
None
StrFind
Module: string :: search
Definition:
StrFind(string base, string sought, int "index", bool "ignorecase")

Description:
A generic substring search function that can return all positions of occurrence of sought inside base (as an array)
or a specific occurrence (as a zero-based index of the array).
Both case-sensitive and case-insensitive searches are supported, controlled by the ignorecase argument.
Notes and conditions on arguments relations:
1] The function defaults to case-sensitive searches and to returning all positions of sought. If only the first
occurence is wanted the index argument must explicilty contain a zero value.

Examples:
a1 = StrFind("abbcdefabcd", "b")
a1 == "2,3,9" (an array)
a2 = StrFind("abbcdefabcd", "B")
a2 == 0 (case-sensitive is the default)
a3 = StrFind("abbcdefabcd", "b", 0)
a3 == 2
StrReplace
Module: string :: search
Definition:
StrReplace(string base, string sought, string rep, int "index", bool "ignorecase", bool "recurse")

Description:
A generic substring replacement function that can replace all occurrences of sought inside base with rep or the
zero-based index'th specific occurrence.
Both case-sensitive and case-insensitive replacements are supported, controlled by the ignorecase argument.
Also, recursive replacements are supported (where the new string after substitution of sought by rep is searched
from the begining for occurence of sought), controlled by the recurse argument.
Notes and conditions on arguments relations:
If recurse is true the rep string must not contain sought as a substring, because this would led to infinite recursion.
The function will immediately throw an error if such a condition is detected.

Examples:
s1 = StrReplace("abbcacbd", "ab", "a", recurse=true)
# s1 == "acacbd"
s2 = StrReplace("abbcacbd", "ab", "a")
# s2 == "abcacbd"
s3 = StrReplace("aBbcabBcaBd", "aB", "A", ignorecase=true, recurse=true)
# s3 == "AcAcAd"
s4 = StrReplace("aBbcabBcaBd", "aB", "A", recurse=true)
# s4 == "AbcabBcAd"
The string :: sprintf module
The $package :: $module module provides StrPrint, a string formatting function with sprintf-like interface.

Required modules
base :: core, numeric :: core, string :: core, string :: search, array :: core, array :: slices,
array :: operators, array :: transforms

Functions
Name Description
StrPrint() An sprintf-like string formatting function...

Constants
None

Variables
None
StrPrint
Module: string :: sprintf
Definition:
StrPrint(string format, val "p01", val "p02", val "p03", val "p04", ..., val "p50")

Description:
An sprintf-like string formatting function.
It permits incorporation of string representations of up to 50 variables into a pre-built expression (the format
string).
It also allows the incorporation of format characters (tabs, linebreaks, etc.).
Very useful for creating subtitles, log entries and function calls or other code strings to be passed to the Eval()
standard avisynth function or other Avisynth, plugin or user functions (for example: to build RPN expressions for
the xxxLut functions of MaskTools).

Arguments:
format: String containing variable substitution placeholders which will be replaced by an appropriate string
representation of the corresponding variable's value (in all cases except %q as a string without double quotes). The
substitution placeholders have the form:
• %b: interpret variable as a bool (replace with "true" or "false").
• %c: interpret variable as a clip; replace with its framecount.
• %f: interpret variable as a float (replace with its value, stripping trailing zeros with ZStrip()).
• %g: interpret variable as a clip; store it as an auto-global and replace with the auto-global's name [1].
• %i: interpret variable as an integer.
• %q: interpret variable as a string; quote it with double quotes before replacing.
• %s: interpret variable as a string.
• %v: interpret variable as having any possible type and replace appropriately after determining it. Clips are
treated as if %c was specified.
Total number of variables (and thus substitution placeholders) accepted is 50.
In addition, the following formating placeholders have a special meaning (and may be present in any number):
• %%: Replace with a % character.
• \n: Replace with a line feed character.
• \r: Replace with a carriage return character.
• \t: Replace with a tab character.
p01, p02, ..., p50 (Optional): The variables that will supply values for replacing the substitution placeholders of
the format string. "

Notes and conditions on arguments relations:


1) All substitution and formatting placeholders' strings are case sensitive.
2) The number of variables must correspond exactly to the number of substitution placeholders contained in
the format string else the function will throw an error.
3) If some of the variables supplied to the function are not defined, they will be treated as non-existent; this
is a feature but it means that you must be careful because substitution of placeholders in the format string
is performed with the order that defined arguments are supplied to the function.
4) You can use the function to perform only formatting substitutions if no variables are supplied and the
format string contains only formatting placeholders.
Examples:
fmt = "Current source is a %ix%i %f fps %s clip ."
c = AVISource(…)
ct = c.IsRGB ? ""RGB"" : (c.IsYUY2 ? ""YUY2"" : ""YV12"")
rst = StrPrint(fmt, c.Width, c.Height, c.Framerate, ct)
return BlankClip().Subtitle(rst)
[1]:%g is useful for creating parameter strings to be passed at array operator functions, in order to convert a local
clip variable to a global variable. The mechanism used to do so is the same as the one used for the implementation
of AVSLib's array type.
The filters package
The filters package contains modules that implement various useful filters (clip transformation functions); for
example animation, editing, resizing and stacking filters.

Required packages
The filters package requires modules from the following packages (see the specific modules' documentation for
actual dependencies): base, numeric, string, array, clip.

Modules
Name Description
This module provides functions, constants and global variables for the implementation of
animate
animation filters.
This module provides functions, constants and global variables for performing operations to clip
channels
channels (extraction, merging, etc.).
This module provides functions, constants and global variables for the implementation of editing
filters (which allow insertion, deletion, replacement, joining, trimming, etc. of clips).
edit
In particular, the ability to specify arbitrary user-functions for the joining of edited clip's parts
allows batch application of transitions and other effects (titles, etc.).
This module provides functions, constants and global variables for the implementation of custom
frames per frame (runtime) filters. The module's filters thus play the role of runtime filters factory
functions.
This module provides functions, constants and global variables for the implementation of
multiedit
multirange editing filters.
This module provides functions, constants and global variables for the implementation of
resize
generic resizing filters.
This module provides functions, constants and global variables for the implementation of
stack
generic video stacking filters.
This module provides functions, constants and global variables for the implementation of
utility
general purpose and utility filters that are not classified elsewhere.
The filters :: animate module
The filters :: animate module provides functions, constants and global variables for the implementation of
animation filters.

Required modules
base :: core, base :: conversion, string :: core, string :: search, string :: sprintf,
array :: core, array :: operators, clip :: core, filters :: resize

Functions
Name Description
LineAnim() Animates a clip between a start and an end frame while in parallel it overlays it on a base ...
PolygonAnim() Animates a clip between each segment of a sequence of frames while in parallel overlays it ...
Continuously animates a clip's position and opacity between a start and end frame, while in
MoveOverlay()
parallel overlays it ...
Continuously animates a clip's size between a start and end frame, while in parallel overlays
ResizeOverlay()
it ...

Constants
None

Variables
None
LineAnim
Module: filters :: animate
Definition:
LineAnim(clip base, clip ovl, int "f_start", int "f_end", int "x_start", int "x_end", int "y_start",
int "y_end", float "op_start", float "op_end", int "w_start", int "w_end", int "h_start",
int "h_end", clip "mask", string "mode", bool "greymask", string "output",
bool "ignore_conditional", bool "pc_range")

Description:
Animates a clip between a start and an end frame while in parallel it overlays it on a base clip using the Overlay()
standard Avisynth function. The clip is animated along with it's mask (a full white as default, if none specified),
thus allowing the application of any overlay mode supported by Overlay().
The filter accepts all arguments of the Overlay() filter, thus providing a general purpose animation interface for
two-point (ie linear) position, opacity and size animation between two frames.

Arguments:
base: The base clip on top of which the animated ovl clip will be overlayed.
ovl: The clip to animate and overlay on top of base clip. If "mask" is not supplied, the function creates a default
full opaque (white) mask equal to the dimensions of the ovl clip.
"f_start" (Optional, defaults to 0): The frame from which the animation will start.
"f_end" (Optional, defaults to base.Framecount-1): The frame where the animation will end.
"x_start" (Optional, defaults to Round(ovl.Width/2)): The starting position of the center [1] of the animated ovl clip
on the horizontal (x) axis.
Thus if x_start is not specified the left side of ovl clip will be, taking into account possible scaling, on top of the
left side of base clip (same behavior with Overlay).
"x_end" (Optional, defaults to x_start): The ending position of the center of the animated ovl clip on the horizontal
(x) axis.
"y_start" (Optional, defaults to Round(ovl.Height/2)): The starting position of the center [1] of the animated ovl
clip on the vertical (y) axis.
Thus if y_start is not specified the top side of ovl clip will be, taking into account possible scaling, on top of the
top side of base clip (same behavior with Overlay).
"y_end" (Optional, defaults to y_start): The ending position of the center of the animated ovl clip on the vertical
(y) axis.
"op_start" (Optional, defaults to 1.0): The starting opacity value of the animated ovl clip.
"op_end" (Optional, defaults to op_start): The ending opacity value of the animated ovl clip.
"w_start" (Optional, defaults to ovl.Width): The starting width of the animated ovl clip.
"w_end" (Optional, defaults to ovl.Width): The ending width of the animated ovl clip.
"h_start" (Optional, defaults to ovl.Height): The starting height of the animated ovl clip.
"h_end" (Optional, defaults to ovl.Height): The ending height of the animated ovl clip.
"mask", "mode", "greymask", "output", "ignore_conditional", "pc_range": They have the same functionality as in
the Overlay() standard Avisynth function. See the Avisynth documentation for details.
Notes and conditions on arguments relations:
1) From version 1.1.0 and onwards, the implementation of the filter is based on ScriptClip(), thus allowing
smaller memory footprint and consequently more complex animations than the previous versions (which
were using the Animate() filter).
2) The filter uses internally the Resize filter in order to execute clip resizing when needed. To control which
specific Avisynth resizer will be used by the filter place a call to SetDefaultResizer with appropriate
parameters before calling the filter.

Examples:
# zoom-in a clip, sliding it top-left to bottom-right
# animate the first 200 frames
bc = AVISource(...) # a 720x480, 600 frames clip
oc = AVISource(...) # a 360x240 clip
# start size: 24x16, end size: 320x240
anim = LineAnim(bc, oc, 0, 200, 12, 360+180, 8, 240+120, \
0.0, 1.0, 24, 360, 16, 240)
...
# stretch a clip, sliding it top to bottom
# animate all clip frames
bc = AVISource(...) # a 720x480, 600 frames clip
oc = AVISource(...) # a 360x240 clip
anim = LineAnim(bc, oc, x_start=360, y_start=60, y_end=240, \
w_start=720, h_start=120, w_end=180, h_end=480)
[1]: Animation filters (currently LineAnim and PolygonAnim) treat parameters specifying overlay clip's (x,y)
position as if they correspond to its center and not to its top-left corner as Overlay() does.
While this may seems odd, it does make the calculation of (x,y) paths simpler because in the general case size will
also be animated. If this convention was not used then at any path point a correction would had to be made for the
changing size of the animated clip at both x and y.
See the tutorial "Understanding animation filters" for details.
[2]: Further examples can be found at the Example Scripts section of the documentation.
PolygonAnim
Module: filters :: animate
Definition:
PolygonAnim(clip base, clip ovl, string f_array, val "x_array", val "y_array", val "op_array",
val "w_array", val "h_array", val "mask", val "mode", val "greymask", string "output",
val "ignore_conditional", val "pc_range")

Description:
Animates a clip between each segment of a sequence of frames while in parallel it overlays it on a base clip using
the Overlay() standard Avisynth filter. The clip is animated on each segment along with it's corresponding mask (a
full white as default, if none specified), thus allowing the application of any overlay mode supported by Overlay().
The filter accepts all arguments of the Overlay() filter, either as arrays or as single values. In the first case each
frame segment has distinct values for the associated parameter; in the later case all frame segments share the same
value for the associated parameter.
Thus, the filter provides a general purpose animation interface for multi-point linear (ie polygonal) position,
opacity and size animation within a set of frames.
Arguments:
base: The base clip on top of which the animated ovl clip will be overlayed.
ovl: The clip to animate and overlay on top of base clip. If "mask" is not supplied, the function creates a default
full opaque (white) mask equal to the dimensions of the ovl clip.
f_array: An array of ints defining the frame numbers of the end-points of each animation segment. f_array must
have at least two elements.
The frame numbers must be placed in strict ascending order (ie f_array[i] < f_array[i+1] for every i) and they
must all be in the range [0..base.Framecount-1].
"x_array" (Optional, defaults to Round(ovl.Width/2)): Either an array of ints with the same number of elements as
f_array if varying ovl x-placement is wanted, or a single value if constant x-placement is wanted.
In the first case the x-placement of ovl is linearly animated in each segment between the specified end-point
values.
In every case x_array specifies the starting position of the center [1] of the animated ovl clip on the horizontal (x)
axis.
Thus if x_array is not specified the left side of ovl clip will be, taking into account possible scaling, on top of the
left side of base clip (same behavior with Overlay).
"y_array" (Optional, defaults to Round(ovl.Height/2)): Either an array of ints with the same number of elements
as f_array if varying ovly-placement is wanted, or a single value if constant y-placement is wanted.
In the first case the y-placement of ovl is linearly animated in each segment between the specified end-point
values.
In every case y_array specifies the starting position of the center [1] of the animated ovl clip on the vertical (y)
axis.
Thus if y_array is not specified the top side of ovl clip will be, taking into account possible scaling, on top of the
top side of base clip (same behavior with Overlay).
"op_array" (Optional, defaults to 1.0): Either an array of floats with the same number of elements as f_array if
varying ovl opacity is wanted, or a single value if constant opacity is wanted.
In the first case the opacity of ovl is linearly animated in each segment between the specified end-point values.
"w_array" (Optional, defaults to ovl.Width): Either an array of ints with the same number of elements as f_array if
varying ovl width is wanted, or a single value if constant width is wanted.
In the first case the width of ovl is linearly animated in each segment between the specified end-point values.
"h_array" (Optional, defaults to ovl.Height): Either an array of ints with the same number of elements as f_array
if varying ovl height is wanted, or a single value if constant height is wanted.
In the first case the height of ovl is linearly animated in each segment between the specified end-point values.
"mask" (Optional, defaults to full white mask): Either an array of clips with one less element than f_array if a
distinct mask on each animation segment is wanted, or a single value if only one mask for the entire animation is
wanted.
When distinct masks are provided, they are applied on a per segment basis, ie the transformation is discontinuous:
mask[i] is applied on segment[i], ie on frames [f_array[i]..f_array[i+1]), mask[i+1] on segment[i+1], ie on frames
[f_array[i+1]..f_array[i+2]), etc., without any smoothing transition between them.
"mode" (Optional, defaults to "blend"): Either an array of strings with one less element than f_array if a distinct
overlay mode on each animation segment is wanted, or a single value if only one overlay mode for the entire
animation is wanted.
When distinct modes are provided, they are applied on a per segment basis, ie the transformation is discontinuous:
mode[i] is applied on segment[i], ie on frames [f_array[i]..f_array[i+1]), mode[i+1] on segment[i+1], ie on frames
[f_array[i+1]..f_array[i+2]), etc., without any smoothing transition between them.
See the Overlay() documentation for the allowed values of this argument.
"greymask" (Optional, defaults to true): Either an array of bools with one less element than f_array if a distinct
greymask setting on each animation segment is wanted, or a single value if only one greymask setting for the
entire animation is wanted.
When distinct greymask settings are provided, they are applied on a per segment basis, ie the transformation is
discontinuous: greymask[i] is applied on segment[i], ie on frames [f_array[i]..f_array[i+1]), greymask[i+1] on
segment[i+1], ie on frames [f_array[i+1]..f_array[i+2]), etc., without any smoothing transition between them.
"output" (Optional, defaults to input colorspace): Has the same functionality as the corresponding argument in the
Overlay() standard Avisynth function and accepts the same values.
See the Overlay() documentation for the allowed values of this argument.
"ignore_conditional" (Optional, defaults to false): Either an array of bools with one less element than f_array if a
distinct ignore_conditional setting on each animation segment is wanted, or a single value if only one
ignore_conditional setting for the entire animation is wanted.
When distinct ignore_conditional settings are provided, they are applied on a per segment basis, ie the
transformation is discontinuous: ignore_conditional[i] is applied on segment[i], ie on frames
[f_array[i]..f_array[i+1]), ignore_conditional[i+1] on segment[i+1], ie on frames [f_array[i+1]..f_array[i+2]),
etc., without any smoothing transition between them.
"pc_range": (Optional, defaults to false): Either an array of bools with one less element than f_array if a distinct
pc_range setting on each animation segment is wanted, or a single value if only one pc_range setting for the entire
animation is wanted.
When distinct pc_range settings are provided, they are applied on a per segment basis, ie the transformation is
discontinuous: pc_range[i] is applied on segment[i], ie on frames [f_array[i]..f_array[i+1]), pc_range[i+1] on
segment[i+1], ie on frames [f_array[i+1]..f_array[i+2]), etc., without any smoothing transition between them.

Notes and conditions on arguments relations:


1. The last point of each segment is the first point of the next one, thus for n segments (edges) n+1 values
are required for end-point settings arrays (such as f_array, x_array, etc.) while n values are required for
segment properties arrays (such as mask, mode, etc.).
2. From version 1.1.0 and onwards, the implementation of the filter is based on ScriptClip(), thus allowing
smaller memory footprint and consequently more complex animations than the previous versions (which
were using the Animate() filter).
3. The filter uses internally the Resize filter in order to execute clip resizing when needed. To control which
specific Avisynth resizer will be used by the filter place a call to SetDefaultResizer with appropriate
parameters before calling the filter.
Examples:
# zoom-in a clip, sliding it from top-left to center
# and then slide it top-right, to dissapear
bc = AVISource(...) # a 720x480, 600 frames clip
oc = AVISource(...) # a 360x240 clip
f_arr = "0,100,200"
xy_path = ArrayCreate(6,4, 360,240, 720+180,-120)
x_arr = xy_path.ArrayDeplex(0, 2)
y_arr = xy_path.ArrayDeplex(1, 2)
wh_size = "12,8, 360,240, 360,240"
w_arr = wh_size.ArrayDeplex(0, 2)
h_arr = wh_size.ArrayDeplex(1, 2)
op_arr = "0,1,1"
result = PolygonAnim(bc, oc, f_arr, x_arr, y_arr, op_arr, w_arr, h_arr)
...
# move a clip top->bottom->top and in parallel
# stretch it on the left-right direction
bc = AVISource(...) # a 720x480, 600 frames clip
oc = AVISource(...) # a 360x240 clip
f_arr = "0,150,300,450,599"
x_arr = 360 # x is const, no need for array
y_arr = "120,240,360,240,120"
wh_size = "360,240, 720,120, 360,240, 720,120, 360,240"
w_arr = wh_size.ArrayDeplex(0, 2)
h_arr = wh_size.ArrayDeplex(1, 2)
op_arr = 1 # opacity is const, no need for array
# use add mode here
result = PolygonAnim(bc, oc, f_arr, x_arr, y_arr, op_arr, w_arr, h_arr, mode="add")
[1]: Animation filters (currently LineAnim and PolygonAnim) treat parameters specifying overlay clip's (x,y)
position as if they correspond to its center and not to its top-left corner as Overlay() does.
While this may seems odd, it does make the calculation of (x,y) paths simpler because in the general case size will
also be animated. If this convention was not used then at any path point a correction would had to be made for the
changing size of the animated clip at both x and y.
MoveOverlay
Module: filters :: animate
Definition:
MoveOverlay(clip base, clip ovl, int "f_start", int "f_end", int "x_start", int "x_end", int "y_start",
int "y_end", float "opac_start", float "opac_end", clip "mask", string "mode",
bool "greymask", string "output", bool "ignore_conditional", bool "pc_range")

Description:
Continuously animates a clip's position and opacity [1] between a start and end frame, while in parallel overlays it
on a base clip. The clip is animated along with it's mask (a full white as default, if none specified), thus allowing
the application of any overlay mode supported by Overlay().

Arguments:
base: The base clip on top of which the size animated ovl clip will be overlayed.
ovl: The clip to animate its size and overlay on top of base clip.
"f_start" (Optional, defaults to 0): The frame from which the animation will start.
"f_end" (Optional, defaults to base.Framecount-1): The frame where the animation will end.
"x_start" (Optional, defaults to Round(ovl.Width/2)): The starting position of the center [2] of the animated ovl clip
on the horizontal (x) axis.
Thus if x_start is not specified the left side of ovl clip will be, taking into account possible scaling, on top of the
left side of base clip (same behavior with Overlay).
"x_end" (Optional, defaults to x_start): The ending position of the center of the animated ovl clip on the horizontal
(x) axis.
"y_start" (Optional, defaults to Round(ovl.Height/2)): The starting position of the center [2] of the animated ovl
clip on the vertical (y) axis.
Thus if y_start is not specified the top side of ovl clip will be, taking into account possible scaling, on top of the
top side of base clip (same behavior with Overlay).
"y_end" (Optional, defaults to y_start): The ending position of the center of the animated ovl clip on the vertical
(y) axis.
"op_start" (Optional, defaults to 1.0): The starting opacity value of the animated ovl clip.
"op_end" (Optional, defaults to op_start): The ending opacity value of the animated ovl clip.
"mask", "mode", "greymask", "output", "ignore_conditional", "pc_range": They have the same functionality as in
the Overlay() standard Avisynth function. See the Avisynth documentation for details.
Examples:
bs = AVISource(...)
ov = AVISource(...)
# Move from 10,10 to 320,240
# change occures between frames 20 and 100
ovs = MoveOverlay(bs, ov, 20, 100, 10, 320, 10, 240)
# zoom out from 960x720 to 320x240
# scale base clip to double size to avoid clipping
# (will feed result to PolygonAnim to animate position)
ovp = ResizeOverlay(bs, ov, 10, 100, 960, 320, 720, 240, 2.0)
[1]: Thisis an intermediate filter used by LineAnim and PolygonAnim filters. Nevertheless it may be useful on
certain occasions and thus it is provided as a "public" AVSLib filter.
[2]: Animation filters treat parameters specifying overlay clip's (x,y) position as if they correspond to its center and
not to its top-left corner as Overlay() does.
While this may seems odd, it does make the calculation of (x,y) paths simpler because in the general case size will
also be animated. If this convention was not used then at any path point a correction would had to be made for the
changing size of the animated clip at both x and y.
ResizeOverlay
Module: filters :: animate
Definition:
ResizeOverlay(clip base, clip ovl, int "f_start", int "f_end", int "w_start", int "w_end",
int "h_start", int "h_end", bool "pcrange")

Description:
Continuously animates a clip's size [1] between a start and end frame, while in parallel overlays it on a base clip.
The overlay is done such that the center of the overlayed clip is always on the center of the base clip,
irrespectively of its size. [2]

Arguments:
base: The base clip on top of which the size animated ovl clip will be overlayed.
ovl: The clip to animate its size and overlay on top of base clip. Note that unlike other animation functions, such
as LineAnim and PolygonAnim, no mask is used.
"f_start" (Optional, defaults to 0): The frame from which the size animation will start.
"f_end" (Optional, defaults to base.Framecount-1): The frame where the size animation will end.
"w_start" (Optional, defaults to ovl.Width): The starting width of the animated ovl clip.
"w_end" (Optional, defaults to ovl.Width): The ending width of the animated ovl clip.
"h_start" (Optional, defaults to ovl.Height): The starting height of the animated ovl clip.
"h_end" (Optional, defaults to ovl.Height): The ending height of the animated ovl clip.
"pcrange" (Optional, defaults to false): Has the same functionality as the pc_range argument of the Overlay()
standard Avisynth function.
Notes and conditions on arguments relations:
1] The filter uses internally the Resize filter in order to execute clip resizing when needed. To control which
specific Avisynth resizer will be used by the filter place a call to SetDefaultResizer with appropriate parameters
before calling the filter.
Examples:
bs = AVISource(...)
ov = AVISource(...)
# zoom in from 10x10 to 320x240
# change occures between frames 10 and 100
ovs = ResizeOverlay(bs, ov, 10, 100, 10, 320, 10, 240)
# zoom out from 960x720 to 320x240
ovp = ResizeOverlay(bs, ov, 10, 100, 960, 320, 720, 240)
[1]: Thisis an intermediate filter used by LineAnim and PolygonAnim filters. Nevertheless it may be useful on
certain occasions and thus it is provided as a "public" AVSLib filter.
[2]: The
filter uses internally the generic Resize filter. Currently, there is no option to specify a resizer in the
argument list and thus resizer selection (if other than the default) must be performed through explicit calls to the
SetDefaultResizer() helper function before invoking the filter.
The filters :: channels module
The filters :: channels module provides functions, constants and global variables for performing operations to clip
channels (extraction, merging, etc.).

Required modules
base :: core, base :: conversion, array :: core, array :: operators, clip :: core

Functions
Name Description
ChannelIndex() Returns the index in a clip channels' array of the specified in ch channel ...
IsRGB24Channels() Returns true if the array channels contains the channels of a RGB24 clip...
IsRGB32Channels() Returns true if the array channels contains the channels of a RGB32 clip...
Returns true if the array channels contains the channels of a RGB (either RGB24 or
IsRGBChannels()
RGB32) clip...
Returns true if the array channels contains the channels of a YUV (either YUY2 or
IsYUVChannels()
YV12) clip...
IsYUY2Channels() Returns true if the array channels contains the channels of a YUY2 clip...
IsYV12Channels() Returns true if the array channels contains the channels of a YV12 clip...
A filter for Avisynth versions up to 2.55 providing equivalent functionality with the
MergeARGB()
corresponding filter of Avisynt...
A filter for Avisynth versions up to 2.55 providing equivalent functionality with the
MergeRGB()
corresponding filter of Avisynt...
MergeVideoChannels() Merges the clips of channels' array channels into a single clip...
MergeYUV() Merges clips clipY, clipU and clipV into a signle YUV clip...
A filter for Avisynth versions up to 2.55 providing equivalent functionality with the
ShowBlue()
corresponding filter of Avisynth...
A filter for Avisynth versions up to 2.55 providing equivalent functionality with the
ShowGreen()
corresponding filter of Avisynth...
A filter for Avisynth versions up to 2.55 providing equivalent functionality with the
ShowRed()
corresponding filter of Avisynth...
ShowU() A YUV filter analogus to the Show{Red/Green...
ShowV() A YUV filter analogus to the Show{Red/Green/Blue}...
ShowY() A YUV filter analogus to the Show{Red/Green/Blue}...
Splits a clip into an array containing the individual clip's channels (R, G, B[, A] or Y,
SplitVideoChannels()
U, V depending on clip's colorspace) ...

Constants
None

Variables
None
ChannelIndex
Module: filters :: channels
Definition:
ChannelIndex(string ch)
Description:
Returns the index in a clip channels' array [1] of the specified in ch channel.
The ch argument must be a signle character string containing one of A, R, G, B, Y, U, V.
Examples:
redid = ChannelIndex("R")
clp_red = channels.ArrayGet(redid)
[1]:See the SplitVideoChannels() function's documentation for further details.

IsRGB24Channels
Module: filters :: channels
Definition:
IsRGB24Channels(string channels)
Description:
Returns true if the array channels contains the channels of a RGB24 clip.[1]
Examples:
# TODO in a later version of AVSLib.
[1]:See the SplitVideoChannels() function's documentation for further details.

IsRGB32Channels
Module: filters :: channels
Definition:
IsRGB32Channels(string channels)
Description:
Returns true if the array channels contains the channels of a RGB32 clip.[1]
Examples:
# TODO in a later version of AVSLib.
1]:See the SplitVideoChannels() function's documentation for further details.
IsRGBChannels
Module: filters :: channels
Definition:
IsRGBChannels(string channels)
Description:
Returns true if the array channels contains the channels of a RGB (either RGB24 or RGB32) clip.[1]
Examples:
# TODO in a later version of AVSLib.
[1]:See the SplitVideoChannels() function's documentation for further details.

IsYUVChannels
Module: filters :: channels
Definition:
IsYUVChannels(string channels)
Description:
Returns true if the array channels contains the channels of a YUV (either YUY2 or YV12) clip.[1]
Examples:
# TODO in a later version of AVSLib.
[1]:See the SplitVideoChannels() function's documentation for further details.

IsYUY2Channels
Module: filters :: channels
Definition:
IsYUY2Channels(string channels)
Description:
Returns true if the array channels contains the channels of a YUY2 clip.[1]
Examples:
# TODO in a later version of AVSLib.
[1]:See the SplitVideoChannels() function's documentation for further details.
IsYV12Channels
Module: filters :: channels
Definition:
IsYV12Channels(string channels)
Description:
Returns true if the array channels contains the channels of a YV12 clip.[1]
Examples:
# TODO in a later version of AVSLib.
[1]:See the SplitVideoChannels() function's documentation for further details.

MergeARGB
Module: filters :: channels
Definition:
MergeARGB(clip clipA, clip clipR, clip clipG, clip clipB)
Description:
A filter for Avisynth versions up to 2.55 providing equivalent functionality with the corresponding filter of
Avisynth 2.56 and later.
The filter is a thin wrapper around the RGB Manipulate plugin developed by tsp. The later provides the core
functionality of RGB channels manipulation.
Arguments:
See the Avisynth 2.56 or later documentation for argument information.
Examples:
# See the Avisynth 2.56 or later documentation for examples.

MergeRGB
Module: filters :: channels
Definition:
MergeRGB(clip clipR, clip clipG, clip clipB, string "pixel_type")
Description:
A filter for Avisynth versions up to 2.55 providing equivalent functionality with the corresponding filter of
Avisynth 2.56 and later.
The filter is a thin wrapper around the RGB Manipulate plugin developed by tsp. The later provides the core
functionality of RGB channels manipulation.
Arguments:
See the Avisynth 2.56 or later documentation for argument information.
Examples:
# See the Avisynth 2.56 or later documentation for examples.
MergeVideoChannels
Module: filters :: channels
Definition:
MergeVideoChannels(string channels)
Description:
Merges the clips of channels' array channels into a single clip.
channels must be in a compatible format with that returned by SplitVideoChannels().
Examples:
"
ch = SplitVideoChannels(AVISource(…))

# process individual channels and update ch elements

proc_clip = MergeVideoChannels(ch)

MergeYUV
Module: filters :: channels
Definition:
MergeYUV(clip clipY, clip clipU, clip clipV)
Description:
Merges clips clipY, clipU and clipV into a signle YUV clip.
Output colorspace is determined by clipY (YUY2 if RGB/YUY2, YV12 if YV12).[1]
Notes and conditions on arguments relations:
1]: Given (w,h) dimensions of clipY, clipU and clipV dimensions must be (w/2,h) if clipY is RGB / YUY2,
(w/2,h/2) if clipY is YV12.
Examples:
# See the MergeRGB() and MergeARGB() documentation for examples.
[1]:All
clip values are treated as pc range (they do not downscale when converting from RGB). See ShowY(),
ShowU() , ShowV() documentation for details.
ShowBlue
Module: filters :: channels
Definition:
ShowBlue(clip c, string "pixel_type")
Description:
A filter for Avisynth versions up to 2.55 providing equivalent functionality with the corresponding filter of
Avisynth 2.56 and later.
The filter is a thin wrapper around the RGB Manipulate plugin developed by tsp. The later provides the core
functionality of RGB channels manipulation.
Arguments:
See the Avisynth 2.56 or later documentation for argument information.
Examples:
#See the Avisynth 2.56 or later documentation for examples.

ShowGreen
Module: filters :: channels
Definition:
ShowGreen(clip c, string "pixel_type")
Description:
A filter for Avisynth versions up to 2.55 providing equivalent functionality with the corresponding filter of
Avisynth 2.56 and later.
The filter is a thin wrapper around the RGB Manipulate plugin developed by tsp. The later provides the core
functionality of RGB channels manipulation.
Arguments:
See the Avisynth 2.56 or later documentation for argument information.
Examples:
#See the Avisynth 2.56 or later documentation for examples.

ShowRed
Module: filters :: channels
Definition:
ShowRed(clip c, string "pixel_type")
Description:
A filter for Avisynth versions up to 2.55 providing equivalent functionality with the corresponding filter of
Avisynth 2.56 and later.
The filter is a thin wrapper around the RGB Manipulate plugin developed by tsp. The later provides the core
functionality of RGB channels manipulation.
Arguments:
See the Avisynth 2.56 or later documentation for argument information.
Examples:
#See the Avisynth 2.56 or later documentation for examples.
ShowU
Module: filters :: channels
Definition:
ShowU(clip c, string "pixel_type")
Description:
A YUV filter analogus to the Show{Red/Green/Blue} RGB filters. It returns the c clip's U channel as a clip with
pixel_type colorspace (or the original if no pixel_type is specified) [1].
Examples:
c = ColorBars().ConvertToYV12()
# get U channel as a full [0..255] range RGB clip
c_u = c.ColorUYV(levels="tv->pc").ShowU("RGB32")
[1]:YUV channels do not upscale if an RGB[32/24] pixel type is requested.
To return a full [0.255] range from an ordinary CCIR YUV clip you will have to manually perform
ColorYUV(levels="tv->pc") before extracting the channels.

ShowV
Module: filters :: channels
Definition:
ShowV(clip c, string "pixel_type")
Description:
A YUV filter analogus to the Show{Red/Green/Blue} RGB filters. It returns the c clip's V channel as a clip with
pixel_type colorspace (or the original if no pixel_type is specified) [1].
Examples:
c = ColorBars().ConvertToYUY2()
# get V channel as a full [0..255] range RGB clip
c_u = c.ColorUYV(levels="tv->pc").ShowV("RGB32")
[1]:YUV channels do not upscale if an RGB[32/24] pixel type is requested.
To return a full [0.255] range from an ordinary CCIR YUV clip you will have to manually perform
ColorYUV(levels="tv->pc") before extracting the channels.
ShowY
Module: filters :: channels
Definition:
ShowY(clip c, string "pixel_type")
Description:
A YUV filter analogus to the Show{Red/Green/Blue} RGB filters. It returns the c clip's Y channel as a clip with
pixel_type colorspace (or the original if no pixel_type is specified) [1].
Examples:
c = ColorBars().ConvertToYV12()
# get Y channel as a full [0..255] range RGB clip
c_u = c.ColorUYV(levels="tv->pc").ShowY("RGB32")
[1]:YUV channels do not upscale if an RGB[32/24] pixel type is requested.
To return a full [0.255] range from an ordinary CCIR YUV clip you will have to manually perform
ColorYUV(levels="tv->pc") before extracting the channels.

SplitVideoChannels
Module: filters :: channels
Definition:
SplitVideoChannels(clip c, string "pixel_type")
Description:
Splits clip c into an array containing the individual clip's channels (R, G, B[, A] or Y, U, V depending on c's
colorspace) and (at index 0) a pixel type string description (thus the array returned is a mixed-type array).[1]
The optional pixel_type argument can be used to convert c to a different colorspace on the fly before returning the
channels.
To access the channels inside the array it is best to use the ChannelIndex() helper function.
Examples:
#open a clip and split into channels converting to YV12
ch = SplitVideoChannels(AVISource(…), "YV12")
# process the Y channel
#don't forget to update the array
yid = ChannelIndex("Y")
ch.ArraySet(yid, ch.ArrayGet(yid).Levels(…))
# do further processing
...
# merge channels when done
rst = MergeVideoChannels(ch)
[1]:Batchprocessing of the entire array is still possible. Simply make the custom function to accept a val (ie any)
Avisynth type and process an element only if IsClip returns true.
The filters :: edit module
The filters :: edit module provides functions, constants and global variables for the implementation of editing
filters (which allow insertion, deletion, replacement, joining, trimming, etc. of clips).
In particular, the ability to specify arbitrary user-functions for the joining of edited clip's parts allows batch
application of transitions and other effects (titles, etc.).

Required modules
base :: core, numeric :: core, string :: core

Functions
Name Description
EditDelete() Deletes a specified number of frames from a clip, starting at a specified frame position...
EditInsert() Inserts a specified number of frames of an insert clip to a base clip, starting at a ...
EditJoin() Joins up to 50 clips sequentially. In particular, the ability to specify arbitrary user-functions...
EditReplace() Replaces a specified number of frames of a base clip with a specified number of frames ...
Returns a portion of a clip. It is intended as a replacement of the Trim standard Avisynth
EditTrim()
filter...

Constants
Name Description
EDOP_ADD Join clip parts after editing using UnallignedSplice (+).
EDOP_ALGN Join clip parts after editing using AllignedSplice (++).
EDOP_DISS Join clip parts after editing using Dissolve().
EDOP_USER Join clip parts after editing using a user-specified function.

Variables
None
EditDelete
Module: filters :: edit
Definition:
EditDelete(clip base, int frame, int "del_frames", int "op", string "extra_info")
Description:
Deletes a specified number of frames from a clip, starting at a specified frame position. The resulting clip will
always have <= length from the base clip.
Arguments:
base: The clip to delete frames from.
frame: The frame-number to start deleting frames (ie the first frame to delete).
"del_frames" (Optional, defaults to base.Framecount ie to the end of clip): The number of frames to delete from
base.
The value of del_frames is always clamp-ed between zero and base.Framecount. Thus negative values have the
same effect as zero (nothing is deleted).
"op" , "extra_info" (Optional): Both have the same semantics as in EditReplace() function.
Examples:
# load a clip to c and then make it 200 frames long
c = AVISource( ... ).EditTrim(0, 200)
# now operate on c; use OOP notation
# delete 10 frames starting from 0 (-10 decrease, 190 total)
d1 = c.EditDelete(0, 10)
# delete 40 frames starting from 80 (-40 decrease, 160 total)
# use Dissolve() to join result parts with overlap=5
d2 = c.EditDelete(0, 10, EDOP_DISS, "5")
# delete all frames to the end starting from 100 (-100 decrease, 100 total)
d3 = c.EditDelete(100)
EditInsert
Module: filters :: edit
Definition:
EditInsert(clip base, clip inclip, int frame, int "ins_frames", int "op", string "extra_info")
Description:
Inserts a specified number of frames of an insert clip to a base clip, starting at a specified frame position. The
resulting clip will always have >= length from base clip.
Arguments:
base: The clip to insert frames to.
inclip: The clip to insert frames from.
frame: The frame-number to start inserting frames (the first frame of inclip will correspond to this number in the
resulting clip).
"ins_frames" (Optional, defaults to inclip.Framecount): The number of frames to insert from inclip (always
starting from the begining of it).
The value of ins_frames is always clamp-ed between zero and inclip.Framecount.
Specifying zero for this argument is the same as ommiting it.
"op" , "extra_info" (Optional): Both have the same semantics as in EditReplace() function.
Examples:
# load a clip to c and d and then make them 200 frames long
c = AVISource( ... ).EditTrim(0, 200)
d = AVISource( ... ).EditTrim(0, 200)
# now operate on c; use OOP notation
# insert 10 frames of d starting from 0 (+10 increase, 210 total)
i1 = c.EditInsert(d, 0, 10)
# insert 50 frames of d starting from 50 (+50 increase, 250 total)
# use Dissolve() to join result parts with overlap=5
i2 = c.EditInsert(d, 50, 50, EDOP_DISS, "5")
# insert entire d at the end of c (+200 increase, 400 total)
i3 = c.EditInsert(d, c.Framecount)
EditJoin
Module: filters :: edit
Definition:
EditJoin(clip c1, clip c2, clip "c3", clip "c4", .... , clip "c50", int "op", string "extra_info")
Description:
Joins up to 50 clips sequentially.
In particular, the ability to specify arbitrary user-functions for the joining allows batch application of transitions
and other effects (titles, etc.).
Arguments:
c1, c2, ... , "c50" (Except c1, c2 all other are optional): The clips to join together.
"op" , "extra_info" (Optional): Both have the same semantics as in EditReplace() function.
Examples:
# load a clip to c and d and then make them 200 frames long
c = AVISource( ... ).EditTrim(0, 200)
d = AVISource( ... ).EditTrim(0, 200)
# now join them (result is 400 frames long)
j1 = EditJoin(c, d)
# lets do something fancier
# Blends last 10 frames of 1st clip with first 10 frames of 2nd
# (this make the result 10 frames shorter than the sum of the clips)
function my_join(clip c1, clip c2) {
sc = c1.EditTrim(0, -10)
ec = c2.EditTrim(10)
mc = Overlay(c1.EditTrim(-10), c2.EditTrim(0, 10), opacity=0.5)
return sc + mc + ec
}
# join using my_join (result is 390 frames long)
j2 = EditJoin(c, d, op=EDOP_USER, extra_info="my_join")
EditReplace
Module: filters :: edit
Definition:
EditReplace(clip base, clip inclip, int frame, int "ins_frames", int "rep_frames", int "op", string "extra_info")
Description:
Replaces a specified number of frames of a base clip with a specified number of frames of an insert clip, starting
at a specified frame position. The operation is the sum of a "Trim" and an "Insert" and thus the resulting clip may
have different length from base clip.
Arguments:
base: The clip to replace frames from.
inclip: The clip to insert frames of (ie the clip that contains the replacement frames).
frame: The frame-number to start replacing from (the frame corresponding to this number is excluded from the
resulting clip).
The value of frame is clamp-ed between zero and base.Framecount. Thus, values <= 0 result in replacement
starting from the start of base clip and values >= base.Framecount in addition of inclip (trimmed to ins_frames
length) to the end of base.
"ins_frames" (Optional, defaults to inclip.Framecount): The number of frames to insert from inclip (always
starting from the begining of it).
The value of ins_frames is always clamp-ed between zero and inclip.Framecount.
Specifying zero for this argument is the same as ommiting it.
"rep_frames" (Optional, defaults to processed value of ins_frames): The number of base clip frames to replace.
The value of rep_frames is always clamp-ed between zero and Max(0, base.Framecount - frame), ie maximum
available frames after frame. Thus, if the replacement is requested near the end of base clip, the replaced frames
may be less than ins_frames.
Specifying zero for this argument is the same as ommiting it.
"op" (Optional): The operation to perform for joining the resulting clip parts after trimming the initial clips.
Accepts one of the EDOP_xxx constants, defined at the filters::edit module. If not supplied, defaults to
EDOP_ADD, ie join with UnallignedSplice(), the "+" clip operator.
"extra_info" (Optional, defaults to ""): Additional information to pass when the op argument is one of
EDOP_DISS (join with Dissolve()) or EDOP_USER (join with a user-supplied function).
In the first case it must be a string representation of an integer, which has the same meaning as the overlap
argument in the Dissolve() standard Avisynth function.
In the second case it must be the name of the user-supplied function.
Examples:
# load a clip to c and d and then make them 200 frames long
c = AVISource( ... ).EditTrim(0, 200)
d = AVISource( ... ).EditTrim(0, 200)
# now operate on c; use OOP notation
# replace 90 frames starting from 0 with 10 frames of d (-80 decrease, 120 total)
r1 = c.EditReplace(d, 0, 10, 90)
# replace 50 frames starting from 100 with 50 frames from d (same length, 200 total)
r2 = c.EditReplace(d, 100, 50)
# replace all frames to the end starting from 120 with entire d (+120 increase, 320
total)
r3 = c.EditReplace(d, 120)
EditTrim
Module: filters :: edit
Definition:
EditTrim(clip base, int fstart, int "fend", int "fcount")
Description:
Returns a portion of a clip. It is intended as a replacement of the Trim standard Avisynth function, providing a
more flexible and easier to use behavior.
Arguments:
base: The clip to trim.
fstart: The frame to start trimming from.
Negative values are allowed and specify the offset from the end of the clip (ie -10 means " start from the frame 10
positions before the end of clip").
"fend" (Optional, defaults to base.Framecount): The frame to end trimming. The end frame does not get included
in the result ie the function always returns the frame interval [fstart..fend).
Negative values are allowed and specify the offset from the end of the clip (ie -10 means "stop at frame 10
positions before the end of clip").
"fcount" (Optional, defaults to zero): The number of frames to include in the result. Accepts only values >= 0
(when zero a null clip (length=0) is returned).
Notes and conditions on arguments relations:
1. fend and fcount are mutually exclusive. If both are supplied the function throws an error.
2. If both fend and fcount are ommited the function returns all frames from fstart to the end of clip.
3. If after processing negative indices and converting fcount (if supplied) to an equivalent fend value,
fstart >= fend the function returns a null clip (length=0).
4. If fend is set to zero the function returns a null clip (length=0), since then the processed
fstart will be >= fend (see note above).
Examples:
# load a clip to c and then make it a 200 frames clip
c = AVISource( ... ).EditTrim(0, 200)
# now operate on c; use OOP notation
fc = c.Framecount
# get frames from 20 to 100, number 20-99 (100 is not included)
t0 = c.EditTrim(20, 100)
# get the first frame only
t1 = c.EditTrim(0, 1)
# get the last frame only
t2 = c.EditTrim(-1) # same as c.EditTrim(fc-1, fc)
# get 5 frames from the end, number 195-199
t3 = EditTrim(c, -5)
# get 15 frames starting 5 frames from the end
# actually only 5 frames will be retrieved, number 195-199
t4 = c.EditTrim(-5, fcount=15)
# get frames from 20 before end up to 10 frames before end, number 180-189
t5 = c.EditTrim(-20, -10)
# get 100 frames from -300 before end, number (-100)-(-1)
# since no frame of c is in that range a null clip (length=0) is returned
t6 = c.EditTrim(-300, fcount=100)
# this is also happens if a zero fcount is supplied or fstart==fend
t7 = c.EditTrim(25, fcount=0)
t8 = c.EditTrim(25, 25)
The filters :: frames module
The filters :: frames module provides functions, constants and global variables for the implementation of
multirange editing filters.

Required modules
base :: core, string :: core, string :: search, string :: sprintf, array :: core, array :: operators, filters :: utility

Functions
Name Description
Applies a (filter) script to each frame of clip orig. The script has in its disposal all
FrameFilter() runtime variables and functions (current_frame, AverageLuma, etc.) plus the following
text-substitution literals...
Applies a (filter) script to each frame of a clip like FrameFilter() but in addition allows
FrameFilterReader() use of (any number of) ConditionalReader-style text files for setting auto-generated
global variables inside the script...

Constants
None

Variables
None
FrameFilter
Module: filters :: frames
Definition:
FrameFilter(clip orig, string script, val "p1", val "p2", val "p3", val "p4", ..., val "p50",
string "vars", bool "show", bool "after_frame")
Description:
Applies a (filter) script to each frame of clip orig. The script has in its disposal all runtime variables and functions
(current_frame, AverageLuma, etc.) plus the following text-substitution literals:
• Any number of the literals ${var1}, ${var2}, ..., for specifying named arguments to the script. They are
substituted with StrReplace inside the script string and are supplied by the vars argument array.[1]
• Up to 50 positional arguments (%? placeholders, as defined in StrPrint). They are supplied by the filter's
p1,...,p50 arguments.[2]
For any text-substitution literal contained inside the script, there must be a corresponding p1...p50 argument or
element of the vars array, else the filter will fail with a ScriptClip error message.
Arguments:
orig: The clip on which ScriptClip with the script resulting from substitution of arguments on script will be called.
script: The runtime script on which textual substitution with filter's variable's arguments will be performed. The
script will then be passed internally by the filter to the ScriptClip standard Avisynth filter.
Typically script will be a multiline string surrounded by triple double quotes ("""); this allows to write naturally
double quoted strings inside the script, as one does in a normal Avisynth script; but this is not enforced.
"p1", ..., "p50" (optional, default to none): Positional arguments to be passed to script. Their values will be
substituted to the script text with the aid of StrPrint. Positional means that the arguments have to be supplied with
the same order that StrPrint-compatible %? placeholders appear inside the script's text.
vars (optional, defaults to none): An array of values/variables/globals to be passed to script. They will replace all
occurences of the correspondind ${varI} literals (I being their 1-based index in the array; be aware that AVSLib
arrays are zero-based indexed) inside script.
Names of globals should be quoted inside the vars array in order to be treated as variables and not as values; use
StrQuote when inserting the element to the array.
show and after_frame (optional): They have the same meaning as in ScriptClip standard Avisynth filter. See the
later's documentation for details.
Examples:
...
LoadModule("avslib", "base", "constants")
LoadModule("avslib", "filters", "frames")
# a not-so-elegant dynamic brightness adjustment ( target_luma, threshold, filename )
FF_DYNAMIC_BRIGHTNESS = """
target_luma = %i
th = %i
logfile = %q
avg_luma = AverageLuma()
excess_luma = avg_luma - target_luma
logfile != "" \
? WriteFile(logfile, "current_frame", "TAB", "avg_luma", "TAB", "excess_luma", "TAB",
"th") \
: last
Abs(excess_luma) > th ? Tweak(bright=-Sign(excess_luma)*(Abs(excess_luma) - th)) :
last
"""
clp = AviSource(...)
FrameFilter(clp, FF_DYNAMIC_BRIGHTNESS, 46, 4, "dyn-bri_log.txt")
[1]:"named" arguments can be contained any times desired inside script. All occurences will be replaced in one
step, with the same textual value, as it is supplied by the corresponding element of vars.
[2]:If you need to include a positional argument more than one time inside the script you will either have to assign
it once to a local script variable and use the variable afterwards or supply it at the p1,...,p50 part of the filter's
argument list as many times and in the correct order as defined inside script.
FrameFilterReader
Module: filters :: frames
Definition:
FrameFilterReader(clip orig, string script, string filenames, val "p1", val "p2", val "p3", val "p4", ..., val "p50",
string "vars", bool "show", bool "after_frame")
Description:
An extension of the FrameFilter filter. Applies a (filter) script to each frame of clip orig. The script has in its
disposal:
• all runtime variables and functions (current_frame, AverageLuma, etc.), plus
• all the text-substitution literals accepted by FrameFilter, plus
• the text-substitution literals ${read1}, ${read2}, ..., ${readN}, N == filenames.ArrayLen.
The later are replaced by FrameFilterReader with the actual auto-generated global variables' names whose values
are set internally by the filter from external files passed in (their path) as elements of filenames with
ConditionalReader. [1]
For any text-substitution literal contained inside the script, there must be a corresponding p1...p50 argument or
element of the vars or filenames arrays, else the filter will fail.
Arguments:
filenames is a CR/LF delimited array of filenames (each filename in a single line). Thus, it is the same as a multi-
line string.
It contains the names of files with ConditionalReader-compatible format that set the variables corresponding to
the ${readI} literals. The type and value of each ${readI} can be anything that suits your script and is supported
by ConditionalReader; it just has to be the same type as that declared in the text file.
orig, script, "p1", ..., "p50", vars, show and after_frame: See the documentation of FrameFilter.
Notes and conditions on arguments relations:
1] If filenames == "", ConditionalReader will not be used by FrameFilterReader. A call with a zero-length
filenames array is the same as calling FrameFilter (provided there are no ${readI} literals in the script).
Examples:
...
LoadModule("avslib", "array", "core")
LoadModule("avslib", "filters", "frames")
# a simple per-frame filter mixer ( filtered )
FF_MIX = """
filtered = %q
${read1} > 0 ? Eval(filtered.ArrayGetString(${read1} - 1)) : last
"""
src = AviSource(...)
ft1 = src.Levels(0,0.95,250,0,255).SubTitle("ft1") # SubTitle() is for illustration
ft2 = src.Levels(0,1.05,255,10,252).SubTitle("ft2")
ft3 = src.Levels(10,1.15,255,0,255).SubTitle("ft3")
FrameFilterReader(src, FF_MIX, "mix.txt", ArrayCreate(ft1, ft2, ft3))
# a sample mix.txt contents (ignore # at the begining):
# type int
# default 0
# R 10 35 1
# R 45 48 2
# R 49 53 1
# R 105 123 3
[1]:${readI} literals can be contained any times desired inside script. All occurences will be replaced in one step,
with the same textual value, as it is supplied by the corresponding text file (through the auto-generated global
variables).
The filters :: multiedit module
The filters :: multiedit module provides functions, constants and global variables for the implementation of
multirange editing filters.

Required modules
base :: core, array :: operators, filters :: edit

Functions
Name Description
Trims a number of ranges of frames from clip c and returns them as a single clip. Joining of
EditTrimRange()
ranges is performed by the EditJoin filter, supporting all of its features...

Constants
None

Variables
None
EditTrimRange
Module: filters :: multiedit
Definition:
EditTrimRange(clip c, string fs, val "fe", int "op", string "extra_info")
Description:
Trims a number of ranges of frames from clip c and returns them as a single clip. Joining of ranges is performed
by the EditJoin filter, supporting all of its features.
Selected ranges can have the same or different lengths, depending on the values of fs, fe and (possibly) on custom
joining user-code. [1]
Arguments:
c: The clip to extract frame ranges from.
fs: An array of frame numbers indicating the start of the frame ranges to be extracted.
fe (optional): An array or a single value (a scalar) indicating the first frame past the end of ranges to be extracted.
If fe is a scalar value, it is interpreted as the number of frames to extract from each range. Thus, the ith range
selected will be [fs(i)..fs(i)+fe).
If fe is not provided it defaults to a scalar value equal to 1. Thus, the ith range selected will be [fs(i)..fs(i)+1), ie
only the frames contained in fs will be selected.
If fe is an array, it must have the same length as fs and then each element of fe is interpreted as the first frame past
the end of the corresponding range. Thus, the ith range selected will be [fs(i)..fe(i)).
op, extra_info (optional): See the documentation of the EditJoin filter.
Examples:
clp = AviSource(...)
...
# select frames [12..21]+[345..354]+[1024..1033]+[4356..4365]
# use AllignedSplice (++) to join
fs = "12,345,1024,4356"
sel1 = clp.EditTrimRange(fs, 10, EDOP_ALGN)
...
# select just the frames 12+345+1024+4356
# use UnallignedSplice (+) to join
fs = "12,345,1024,4356"
sel2 = clp.EditTrimRange(fs)
...
# select frames [12..339]+[345..811]+[1024..3566]+[4356..6744]
# join parts using Dissolve(p1, p2, 10)
fs = "12,345,1024,4356"
fe = "340,812,3567,6745"
sel3 = clp.EditTrimRange(fs, fe, EDOP_DISS, "10")
[1]:For selecting single-frame ranges or constant-size ranges without any special join operation, the use of the
standard Avisynth filters SelectEvery / SelectRangeEvery may be more appropriate.
The filters :: resize module
The filters :: resize module provides functions, constants and global variables for the implementation of generic
resizing filters.

Required modules
string :: core, string :: sprintf, numeric :: rounding, array :: properties, clip :: core

Functions
Name Description
GetDefaultResizer() Returns the current default resizer that is used by the Resize... family of filters...
A generic resize filter. Uses any of the standard Avisynth resize filters, either set
Resize()
previously by a call to ...
Resizes clip c such that it fits inside the rectangle specified by width target_w and height
ResizeToFit()
target_h...
ResizeToTarget() Resizes base clip to the same dimensions that target clip has, ...
SetDefaultResizer() Sets the default resizer that is used by the Resize... family of filters when the...

Constants
Name Description
A ResizeToFit() filter-specific constant. Orders that the clip to be resized will be zoomed (in
RTF_ZOOM or out) to match the desired dimensions. Clip's aspect ratio will be preserved, but black bars
to fill the remaining space, if any, may appear.
A ResizeToFit() filter-specific constant. Orders that the clip to be resized will be zoomed so
RTF_CROP that it covers the entire area set by the desired dimensions; parts that fall out will be cropped.
Clip's aspect ratio will be preserved.
A ResizeToFit() filter-specific constant. Orders that the clip to be resized will be stretched to
RTF_STRETCH
fit exactly the desired dimensions. Clip's aspect ratio may change as a result.

Variables
None
GetDefaultResizer
Module: filters :: resize
Definition:
GetDefaultResizer(bool "with_params")
Description:
Returns the current default resizer that is used by the Resize... family of filters when the resizer parameter does
not explicitly be supplied to them.
If with_params is true then any additional parameters used by the resizer are returned as well, in the order
supplied to SetDefaultResizer(), making the return value an array [1]. Else a single string is returned.
Examples:
oldrsz = GetDefaultResizer(true)

items = oldrsz.ArrayLen
dummy = SetDefaultResizer(oldrsz.ArrayGet(0), (items > 1 ? oldrsz.ArrayGet(1) :
Undef()), (items > 2 ? oldrsz.ArrayGet(2) : Undef()))
[1]:If the current resizer does not require any additional parameters an array of length 1 (ie a simple string) is
returned.
Resize
Module: filters :: resize
Definition:
Resize(clip c, int target_width, int target_height, float "src_left", float "src_top",
float "src_width", float "src_height", string "resizer", val "rsz_param1",
val "rsz_param2", bool "interlaced")
Description:
A generic resize filter. Uses any of the standard Avisynth resize filters, either set previously by a call to
SetDefaultResizer() or directly requested through the resizer argument.
Useful when full flexibility regarding the specific resizer used is wanted (for example in library functions or
modules). Moreover, since it is implemented in C++, the speed penalty from using the filter compared to a
standard Avisynth resizer is negligible.
Arguments:
c, target_width, target_height and (optional) src_left, src_top, src_width, src_height: Same as the corresponding
standard Avisynth ResizeXXX filters' arguments.
resizer, rsz_param1, rsz_param2 (Optional): See the SetDefaultResizer() documentation.
interlaced (Optional, defaults to false): Set it to true if the clip c is an interlaced one.
Notes and conditions on arguments relations:
1] The filter always returns a clip with the correct width and height for its colorspace (taking also into account the
value of interlaced argument), regardless of the values of target_width, target_height. This makes it especially
suitable for size animation, since it does not produces errors for intermediate values of those parameters.
2] If a very small width or height (down to zero) is requested, the filter does not throw an error as the standard
Avisynth resizers do, but instead it uses Crop to achieve the requested dimensions (zero results in the least
dimension supported by the clip's colorspace). Condition 1] above applies also in this case.
The actual (width,height) threshold values where a call to Crop is triggered are (12,8), respectively. These are
higher by 4 from the minimum allowable values of standard Avisynth resizers in order to provide improved
resistance in generation of errors from GetResamplingPattern when very steep resize ratios are requested from
resizers with large support value.
3] The library default resizer (the one that is used when no resizer argument is passed to the filter and no calls to
SetDefaultResizer() have been made previously) is BilinearResize.
Examples:
c = AVISource(…)
# resize with current / default resizer
d = c.Resize(720, 480)
# do a bicubic resize (b=0, c=1/2)
e = c.Resize(720, 480, resizer="Bicubic", rsz_param1=0, rsz_param2=1/2)
...
# make bicubic, b=0, c=1/2 the default
dummy = SetDefaultResizer("Bicubic", 0, 1/2)
f = c.Resize(720, 480)
# now f == e
ResizeToFit
Module: filters :: resize
Definition:
ResizeToFit(clip c, int target_w, int target_h, int "mode", string "resizer", val "rsz_param1", val "rsz_param2",
bool "interlaced")
Description:
Resizes clip c such that it fits inside the rectangle specified by width target_w and height target_height.
There are three possible resize modes (zoom, crop, stretch) that are selected by using proper values for the mode
argument (one of the constants RTF_ZOOM, RTF_CROP, RTF_STRETCH defined at the filters::resize module).
Default mode is zoom (the clip is zoomed so that it fits in at least one of its dimensions to the target rectangle).
This mode may make the result to have black borders (either horizontal or vertical). Aspect ratio is retained.
In crop mode the clip completely covers the target rectangle possibly leaving out some parts by cropping. Aspect
ratio is retained.
In stretch mode the clip may change aspect ratio since then it is forced to fit the target rectangle in both
dimensions.
Arguments:
c: The clip to be resized.
target_w: The target width to resize the clip. If it is zero, then the clip's width will remain unaltered.
target_h: The target height to resize the clip. If it is zero, then the clip's height will remain unaltered.
mode (optional): Controls the way that clip c will be resized to fit the target dimensions (see above).
resizer, rsz_param1, rsz_param2, interlaced (optional): Have the same function as the Resize() filter.
Notes and conditions on arguments relations:
1] If target_w, target_h do not have a value appropriate for the clip's colorspace the filter will throw an error.
2] In both zoom and crop modes the clip is centered to the target rectangle. Thus two black bars will appear (zoom
mode) and two slices will be croped out (crop mode) in either side of the specific clip dimension chosen by the
filter.
3] The filter uses internally the Resize filter in order to execute clip resizing when needed. To control which
specific Avisynth resizer will be used by the filter place a call to SetDefaultResizer with appropriate parameters
before calling the filter.
Examples:
clp = AVISource(...)
# zoom to fit inside a 360x240 rectangle; use Lanczos4Resize c1 = clp.ResizeToFit(360,
240, resizer="lanczos4")
# from now on use Spline36Resize old = SetDefaultResizer("spline36")
# crop to fit inside a 360x240 rectangle c2 = clp.ResizeToFit(360, 240, RTF_CROP)
# stretch to fit inside a 360x240 rectangle c3 = clp.ResizeToFit(360, 240,
RTF_STRETCH)
# stack results Stack(ArrayCreate(c1, c2, c3), 2, 2)
ResizeToTarget
Module: filters :: resize
Definition:
ResizeToTarget(clip base, clip target, string "resizer", val "rsz_param1",
val "rsz_param2", bool "interlaced")
Description:
Resizes base clip to the same dimensions that target clip has, possibly with a colorspace conversion.
The later is done only if calling the Resize filter to adjust dimensions would crash Avisynth (at least on some
versions) or would result in an error dialog box. This on turn depends both on base's and target's colorspaces and
on target's dimensions.
Arguments:
resizer, rsz_param1, rsz_param2, interlaced (optional): Have the same function as the Resize() filter.
Notes and conditions on arguments relations:
1] The filter uses internally the Resize filter in order to execute clip resizing when needed. To control which
specific Avisynth resizer will be used by the filter place a call to SetDefaultResizer with appropriate parameters
before calling the filter.
2] If target is a badly cropped (for its colorspace) source or if a wrong interlaced argument is passed to the filter,
the final dimensions of the returned clip may deviate slightly from the dimensions of target clip, due to the
behavior of the Resize filter. This is however a condition that is not encountered in normal use situations.
Examples:
c = AVISource(...)
#default to lanczos resizing with Avisynth-default taps
dummy = SetDefaultResizer("lanczos")
d = AVISource(...)
d = d.ResizeToTarget(c)
# d now has same dimensions as c (with the only possible
# exception of c being a badly cropped source)
SetDefaultResizer
Module: filters :: resize
Definition:
SetDefaultResizer(string resizer, val "rsz_param1", val "rsz_param2")
Description:
Sets the default resizer that is used by the Resize... family of filters when the resizer parameter does not explicitly
be supplied to them.
Thus, SetDefaultResizer is the master mechanism for the user to control which resizer a filter will use; simply
place a call to SetDefaultResizer with adequate arguments before calling the resizing filter.
Note that since Resize is used internally by many AVSLib filters (such as for example LineAnim, StackToFit,
etc.), setting the resizer with SetDefaultResizer affects any subsequent calls to those filters in the script.
Arguments:
resizer: The name of the resizer. One of "Bicubic", "Bilinear", "Lanczos", "Lanczos4", "Spline16", "Spline32",
"Gauss" or "Point" ie the first part of a specific Avisynth resize filter. Passing the entire filter name of the resizer is
also supported.
rsz_param1, rsz_param2 (Optional): Additional parameters needed by the resizer (for example b, c for
BicubicResize, taps from LanczosResize, etc.); see Avisynth documentation for details.
Notes and conditions on arguments relations:
1] After a call to SetDefaultResizer, all subsequent invocations of any of the Resize... family of filters (and thus
any filter also that uses them internally) will use the resizer specified, until the next call to SetDefaultResizer
(unless of course specific values are passed to them as arguments).
2] The initial library default for resizer is "Bilinear". This is the resizer that will be used if no call to
SetDefaultResizer has been made inside the script.
Examples:
#default to bicubic resizing with b=0, c=1/2
dummy = SetDefaultResizer("Bicubic", 0, 1/2)
# now call a filter that uses Resize
clip2 = clip1.ResizeToFit(720, 480, RTF_ZOOM)
The filters :: stack module
The filters :: stack module provides functions, constants and global variables for the implementation of generic
video stacking filters.

Required modules
base :: core, base :: conversion, array :: core, array :: slices, array :: operators, array :: transforms,
array :: properties, string :: core, string :: sprintf, clip :: core, clip :: arrays, filters :: resize

Functions
Name Description
Stack() Stacks the clips contained in clips array to a nrows x ncols matrix ...
Stacks the clips contained in clips array to a rectangular matrix such as the resulting clip has
StackToFit()
target_w width and target_h height. The clips...

Constants
None

Variables
None
Stack
Module: filters :: stack
Definition:
Stack(string clips, int nrows, int ncols)
Description:
Stacks the clips contained in clips array to a nrows times ncols matrix [1].
Notes and conditions on arguments relations:
1] If the number of clips array elements is less than the product of nrows with ncols the filter fills the remaining
cells with black clips.
2] If the number of clips array elements is greater than the product of nrows with ncols the filter discards the last
excess elements of clips array.
Examples:
c1 = AVISource(…)
c2 = AVISource(…)
c3 = AVISource(…)
c4 = AVISource(…)
a = ArrayCreate(c1,c2,c3,c4, c2,c1,c4,c3, c3,c4,c1,c2, c4,c3,c2,c1)
return Stack(a, 4, 4)
[1]: All clips must have same properties (width, height, fps, etc.) else a related Avisynth error will be thrown.
StackToFit
Module: filters :: stack
Definition:
StackToFit(string clips, int target_w, int target_h, int "mode", string "pixel_type", clip "audio",
string "resizer", val "rsz_param1", val "rsz_param2", bool "interlaced")
Description:
Stacks the clips contained in clips array to a rectangular matrix such as the resulting clip has target_w width and
target_h height. The clips contained in clips array are enlarged or shrinked as necessary.
Clips are converted to the dominant colorspace, unless a specific setting is enforced by the pixel_type argument.
The output clip has the audio of the first clip, unless a clip is passed in by the audio argument.
Clips must have the same framerate, else an error occurs. They can though have different dimensions.
Arguments:
mode (optional): Has the same function as the ResizeToFit() filter for each individual clip in the matrix [1].
resizer, rsz_param1, rsz_param2, interlaced (optional): Have the same function as the Resize() filter.
Notes and conditions on arguments relations:
1] The filter uses internally the Resize filter in order to execute clip resizing when needed. To control which
specific Avisynth resizer will be used by the filter place a call to SetDefaultResizer with appropriate parameters
before calling the filter.
Examples:
clp = ArrayCreate(AVISource(.), ..., AVISource(.))
...
stack in a 720x480 clip, without changing aspect ratio or cropping
black areas between clips may appear
c1 = StackToFit(clp, 720, 480, RTF_ZOOM)
stack in a 720x480 clip, without changing aspect ratio and without
allowing for black areas between clips; take audio from 2nd clip
c2 = StackToFit(clp, 720, 480, RTF_CROP, audio=clp.ArrayGet(1)))
[1]:Each clip of the array resizes individually within the bounds calculated by the partitioning of the target_w x
target_h rectangle to cells with mode supplied by the mode argument (zoom, crop, stretch - default is zoom).
Thus, clips are allowed to have different dimensions and aspect ratios.
The filters :: utility module
The filters :: utility module provides functions, constants and global variables for the implementation of
multirange editing filters.

Required modules
base :: core, clip :: core, array :: core

Functions
Name Description
ConvertToTarget() Converts a clip to a target clip's colorspace...
Applies a filter successively on a clip (thus, implements a chain of filters), each time with
FilterChain()
the same arguments, a specified number of times...
Applies a filter successively on a clip (thus, implements a chain of filters), possibly with
FilterVarChain()
different arguments for each specific subgroup of the chain, a specified number of times...
ScaleToPC() Scales a clip to PC range ([0..255]) if it is YUV. Else returns it unchanged...
ScaleToTV() Scales a clip to CCIR range ([16..235]) if it is YUV. Else returns it unchanged...

Constants
None

Variables
None
ConvertToTarget
Module: filters :: utility
Definition:
ConvertToTarget(clip base, clip target)
Description:
Converts base to target's colorspace.
Examples:
ct = AVISource(...).ConvertToYV12
cb = AVISource(...)
cb = cb.ConvertToTarget(ct) # now cb is YV12

FilterChain
Module: filters :: utility
Definition:
FilterChain(clip c, string filter, int times, string "fparams")
Description:
Applies filter with arguments (c, fparams) times times. fparams must contain the arguments to be passed to filter
as an argument list (separated with commas).
Notes and conditions on arguments relations:
1]: If fparams is not supplied or is "" then filter is called with clip c as its sole argument.
2]: If times is zero or less the filter returns c unmodified.
3]: The first filter's argument (clip c) must not be included in fparams.
Examples:
# make a large gaussian blur by applying Blur 100 times
clp = clp.FilterChain("Blur", 100, "1.57")
# Reduce by 16
clp = clp.FilterChain("Reduceby2", 4)
FilterVarChain
Module: filters :: utility
Definition:
FilterVarChain(clip c, string filter, string var_times, string var_params)
Description:
Applies filter with varying arguments on each call with a varying number of times for each call.
Arguments:
c: The clip to apply filter to.
filter: The filter to apply to clip c. It can be a built-in or plugin filter or any user-defined function.
var_times: An array whose elements is the number of times to apply filter with the parameters contained at the
corresponding var_params array's element.
var_params: A CR/LF delimited array (ie a multiline Avisynth string) containing at each line the arguments to be
passed to filter as an argument list (separated with commas).
Notes and conditions on arguments relations:
1]: If for a filter 's invocation the associated element of var_params is "" then filter is called with clip c as its sole
argument.
2]: If for a filter 's invocation the associated element of var_times is zero or less, the filter is not applied for that
invocation.
3]: The first filter's argument (clip c) must not be included in var_params's elements.
Examples:
# trim-out ranges [50..100), [150..175), [200..225), [500..537)
# apply a dissolve in the last trim-out
# note that ops are applied successively, thus framenumbers
# must be recalculated on each invocation
vars = """50,25
100,25
125,25
400,37,EDOP_DISS,"10" """
clp = AviSource(...)
clp2 = FilterVarChain(clp, "EditDelete", "2,1,1,1", vars)

ScaleToPC
Module: filters :: utility
Definition:
ScaleToPC(clip c)
Description:
Scales c to PC range ([0..255]) if it is YUV. Else returns it unchanged.
Examples:
c = AVISource(...)
mask = c.ScaleToPC()
ScaleToTV
Module: filters :: utility
Definition:
ScaleToTV(clip c)
Description:
Scales c to CCIR range ([16..235]) if it is YUV. Else returns it unchanged.
Examples:
c = AVISource(...)
mask = c.ScaleToPC()
...
mclp = mask.ScaleToTV()
Installation Instructions

Downloading the right version of AVSLib


AVSLib distributions will be either production versions or alpha or beta versions of the library. Alpha and beta
versions will always include a notice about this fact (the terms "alpha" or "beta" inside parentheses as part of the
name of the distribution). All other distributions not containing such a notice will always be production versions
of the library.
In general, unless you want to participate in the testing of AVSLib or you are a developer of extensions to
AVSLib, you should download the latest production or beta version (the one with the larger version number) from
the AVSLib download page.

Installing AVSLib
From version 1.1.0 AVSLib comes with a full featured installer. A source-only distribution is also provided for
manual installation, in case anyone faces a problem with the installer.

Standard (recommended) installation procedure


The standard installation procedure is very simple; download and run the installer, then follow the on screen
instructions.

Manual installation procedure


1. Unpack the entire contents of the downloaded source-only distribution's archive to the selected
destination folder in your hard drive.
Be sure to check that unpacking will recreate the archived contents folder structure.
2. Open the destination folder with Windows Explorer and locate the files loader.avsi and avslib.avsi.
3. Open the file avslib.avsi in a text editor.
4. Enter at the end of the last line (the one containing "__LIBROOT_AVSLIB = ") the full path to the
destination folder where you had unpacked the distribution in step 1. Don' t forget to surround the path
with double quotes!
5. Save the modified file.
6. Copy loader.avsi and avslib.avsi to Avisynth's plugins folder (the one that is used for plugin autoloading).
7. (Optionally) create a shortcut to the AVSLib documentation on your desktop.

Using AVSLib
To use AVSLib, load into your scripts the modules that contain the desired functionality. You can use any
combination of the LoadLibrary(), LoadPackage() and LoadModule() functions for this. See the packages
documentation to locate the modules that contain the filters and functions you want to use.
With LoadLibrary(), which loads entire parts of the AVSLib library, you can use the following predefined
constants:
• CONFIG_AVSLIB_FULL : Loads the entire AVSLib library.
• CONFIG_AVSLIB_SCRIPT : Loads only scripting enhancements (the base, numeric, string and debug
packages (and any required by them modules).
• CONFIG_AVSLIB_ARRAYS : Loads only the array package (and any required by them modules).
• CONFIG_AVSLIB_FILTERS : Loads only the filters and clip package (and any required by them
modules).
The preferred place in your script to place the calls to the load functions is the begining, but this is not necessary.
As long as you load the modules before using their functions, you can put the calls to LoadLibrary(),
LoadPackage() and LoadModule() anywhere in your script.
Solving installation problems
If the installer encounters problems during the installation, it will notify you of these. Workaround the pointed out
problems and rerun the installer.
If your problem persists, check if a solution is described at the FAQs section of the documentation, or post a
support request at the Help / Support AVSLib project's forum.
You may also try the manual installation procedure from the source-only distribution described above.

Uninstalling AVSLib

Standard (recommended) installation procedure


Run the uninstaller and follow the on screen instructions.

Manual installation procedure


• Delete the destination folder where you have had unpacked the AVSLib distribution.
• Delete loader.avsi and avslib.avsi to Avisynth's plugins folder (the one that is used for plugin
autoloading).
FAQs

General questions

1. What is AVSLib?
AVSLib is an extension library for the Avisynth script language. It offers a general-purpose toolkit to
Avisynth script developers for enhancing their ability to perform complex linear and non-linear video editing
tasks (such as creating timelines, editing and animating clips, etc.) as well as tools to debug scripts, a rich set of
functions to handle script variables, new datatypes (arrays and maybe later matrices and dictionaries) and many
more.

2. What makes AVSLib different from other plugins I have found for
Avisynth?
AVSLib is a script language extension library. It provides general-purpose code objects (functions,
constants, custom datatypes, etc.) that extend the features offered to script developers from the host script
language.
To state it in other words, most plugins concentrate on the fulfillment of a specific (usually narrow) set of
tasks, while AVSLib concentrates on providing the "glue" that allows effective scripting of both Avisynth's
standard tools and plugins.

3. What are the licencing terms of AVSLib?


See the licence page for information.

4. Where can I download the latest version of AVSLib?


Both the latest and older versions of AVSLib are available from the AVSLib project page at SourceForge.

5. Where can I find documentation for AVSLib?


You can find documentation for AVSLib in the following places:
* Inside each installation package that is available for download from the AVSLib project page .
* Online, at the AVSLib home page.

6. What are the plans for the future?


See the AVSLib project's roadmap.
Installation

1. How do I install AVSLib?


Installation instructions are provided at a separate page of the documentation.

2. How do I install multiple versions of AVSLib?


You just install them in different folders and use the proper importing mechanism of each version in your
scripts.
Note that 1.0.x and 1.1.x importing mechanisms are completely different.
For example:
Suppose you want to install versions 1.0.0 and 1.1.0 under the C:\Program Files\AVSLib\ main folder.
You may choose the following destinations for each of the above distributions:
* C:\Program Files\AVSLib\version_1-0-0
* C:\Program Files\AVSLib\version_1-1-0
Now in order to use each version in you scripts (assuming full features are wanted), you will add the
following line into your script:
Version 1.0.0:
Import("C:\Program Files\AVSLib\version_1-0-0\headers\avslib-h.avsi")
Version 1.1.0:
LoadLibrary("avslib", CONFIG_AVSLIB_FULL)

3. I want a partial install of AVSLib, how can it be accomplished?


There is no need for a partial install. From version 1.1.0 and later AVSLib allows selective loading into
your scripts of only the desired features, through the use of the loader module.
See the LoadModule(), LoadPackage() and LoadLibrary() documentation for details. Also the "Using the
loader module to build Avisynth script libraries" tutorial.

4. How do I know what version of AVSLib I have installed in my system?


Enter the following lines of code to a script:
LoadModule("avslib", "base", "version")
AVSLibVersion()
Note that this will only work for version 1.1.0 and later.

5. How do I uninstall AVSLib?


Depending of your type of install, either run the provided uninstaller or simply delete all associated files.
See the "Uninstalling AVSlib" section of the installation instructions page for details.
Usage

1. Are there any limitations in AVSLib?


In principle not; the code of AVSlib itself has been designed to be as generic and robust as possible.
However, since AVSLib uses the machinery provided by Avisynth in order to provide its services, it does
get limited in various aspects by the resources made available to scripts by the host application (ie Avisynth).
In addition, video editing is a resource instensive operation and thus there are resource limitations
imposed by the hosting hardware and operating system.
The consequence is that - depending also on the Avisynth version that you use - there are practical
limitations, a list of which has been compiled to a dedicated AVSLib specifications page. Please take the time to
read it carefully before starting developing scripts with AVSlib.

2. Will these limitations be removed in a future version of AVSLib?


The answer to this question depends mainly on factors external to the project and thus it cannot be
answered directly by the AVSLib project.
The AVSlib development team has the intention to try devising smarter ways for utilising the given
resources available to Avisynth scripts but this is at this time lower in priority compared to the horizontal
expansion of AVSLib features (ie features increase).

3. Are there any recommendations regarding the use of AVSLib features?


Yes. See the Reserved Actions section at the AVSLib structure page and all tutorials included at the
documentation.
You may also examine the example scripts included at the documentation to see real cases of script
development using AVSLib.

4. I try to run a script containing calls to AVSLib functions and I get the "I
don't know what xxx means" error from Avisynth. What's going
wrong?
Either you have mispelled an AVSLib function name or you didn't supply the correct module or package
or library configuration constant to LoadModule(), LoadPackage() or LoadLibrary() or you didn't install
properly the AVSLib distribution.
Check the above cases in the order specified, until you find the cause and repair the error.
See the installation and use instructions page for details.

5. I get unexpected errors pointing to array operator functions


(ArrayOpValue / ArrayOpFunc / ArrayOpArray / ArrayOpArrayFunc).
Didn't you tested them for errors?
Yes, we did; many times. Most probably the errors are not located in operator functions but inside the
user-code that you have ordered them to execute.
See the last section of the container operators tutorial for best-coding guidelines and ways to debug your
script.
6. My animation gets out of the clip area. What's going wrong?
Animation filters use a different coordinate system than Overlay does. (x,y) values passed to them are
interpreted as specifying the position of the center of the clip and not its top-left corner. Add
Round(ovl.Width/2) to all x's and Round(ovl.Height/2) to all y's to solve the problem.
You may also see the tutorial "Understanding animation filters" for getting a better insight on animation
filters.

7. VirtualDub either crashes or displays a "sctip open failed!" messagebox


when I try to run a script containing AVSLib commands. What's
going wrong?
Most probably your code has hit onto a resource limit (memory is the first to look, especially if it took a
long time before the error appeared). Break your script to a number of succesive scripts (ie construct a script
chain) to lower the memory requirements of each step.
Other possible causes include:
➢ A logical error inside your script (such as producing a NaN, or specifying zero dimensions for a clip, etc.)
that fires an illegal condition either inside AVSLib's or inside Avisynth's code.
➢ Your code has hit onto either an AVSLib's or an Avisynth's internal error (bug).
Try to isolate the error using the facilities of the debug package (the Break() and BreakIf() functions are
especially useful for this) and decide which case of the above is more plausible. Afterwards either recode your
script or ask for support from the corresponding project.

8. I made a script using arrays but I always get a "__left_str: string has >
1024 chars" message when I try to run it. What's going wrong?
You are using Avisynth version 2.5.5 or lower and you are trying to construct an array with overall size
that exceeds the allowable array lenght (ie string lenght) limits. See the AVSLib specifications for details.
To workaround this either upgrade your Avisynth dll to a version greater than 2.5.5 or recode your script
to use smaller arrays.

9. I try to use the EditJoin filter with a custom join function but I get an
"invalid arguments to function..." error? What's going wrong?
Both the join function and the operation argument (extra_info and op, respectively) must be specified
with positional notation:
EditJoin(c1, c2, ..., op=EDOP_USER, exta_info="my_func")
Support

1. I want to submit a bug report. What should I do?


Bug reports should be submitted using the AVSLib project's bug tracker system.

2. I want a feature not included in AVSLib. How can I request it?


Feature requests should be made using the AVSLib project's features request system.

3. Where can I find support about using AVSLib?


The first place to look for support is the documentation (you are viewing it already).
The next place is the Help / Support AVSLib project's forum.
Please, review carefully the documentation before posting any question to the forums. Most of the time
the answer will be there. Also note that questions that are clearly answered by the documentation (such as
"...what does the xxx argument of yyy function does?...", "...what is the purpose of function xxx?...", etc.) will
have little chance of being answered at all.
For submitting bug-reports and feature requests use the corresponding trackers (see FAQs no #1 and #2
above).
Direct e-mails for support to AVSlib developers will be ignored. This communication channel is reserved
for other purposes.

4. I have a question about AVSLib. Where do I seek for an answer?


For any question, you can seek for an answer to one of the following places:
1. Inside this documentation (an online version can always be found at AVSLib's home page).
2. At the most appropriate of the AVSLib project's forums. If the already posted content cannot answer your
question, you may post a new message there.

5. Where can I contact the developers of AVSLib?


Either post a message at the most appropriate of the AVSLib project's forums or use this contact form.
Contribution

1. I want to participate on AVSLib development. How can I do this?


Register with the SourceForge website and then make a request to join the AVSLib project as a developer.

2. I want to contribute texts or script examples to AVSLib documentation.


How can I do this?
Post the related texts / source code at the Contribution AVSLib project's forum. The texts / source code
must be accompanied by a licence compatible with those used by the AVSLib project. See the licence page for
details.
Structure of the AVSLib library

Library Structure
The library is structured around modules. Each module contains related filters, functions and (possibly) global
variables and constants.
Modules with common characteristics are further organised into packages. A package is thus a set of modules with
related scope of operation.
A package may in turn be further divided to (an unlimited depth of) sub-packages. The later typically happens
when the number of modules is getting big and their puprose can be grouped to broader categories.

Library Specifications
Feature Specification
Maximum allowed string length. This is 2^32-1 for Avisynth versions
Maximum array lenght >= 2.5.6 and only 1024 for Avisynth version 2.5.5 and earlier (achieved
with a hack developed by AVSLib).
Variable, depending on the length of the string representation of each
element and the delimiter in effect.
Maximum number of array elements For Avisynth versions >= 2.5.6 is practically unlimited (>> 1 million);
for Avisynth version 2.5.5 and earlier is rather small (around 50 - 150,
depending on the types stored inside the array).
Maximum number of auto-clip globals Maximum allowed int (MAX_INT) plus one (currently 2^32)
All, except some very specific string-related quirks with specific values.
In detail: because containers' handler functions try to evaluate
elements (calling Eval() on them) when they are accessed, certain
operations with strings cannot be performed.
Supported operations on array elements
For example: adding "not" to all elements of a string array with an
array operator does not work as intended. "Not" (remember Avisynth is
case-insensitive) is an AVSLib function ie a global identifier.
See the containers and operators tutorials for details).
Maximum nesting depth / arguments' Limited only by available stack space and range of the result's datatype
values on itterative function calls allowed by Avisynth.
Maximum number of calls to Limited only from available memory space allowed by Avisynth or/and
filters/functions inside scripts. the operating system (maximum process memory size).
Any (no reports up to now for non-functioning features in a specific
version).
Supported Avisynth versions The parts of AVSLib that base their functionality on external plugins
may be limited by plugin-specific limitations (most notably, they will
not work on 2.0.x versions).
In typical library's usage, especially for Avisynth version 2.5.6 and later, it is unlikely that any "hard" limit will be
reached. If a limit is reached it is likely to be a resource limit imposed by Avisynth or the operating system.
If this is the case, rearrange the script in groups of smaller scripts (ie divide and conquer). Keep in mind that many
parts of the library (especially array-related) are "dense", meaning that even a single line in the script (depending
of course on line's contents) if expanded to equivalent Avisynth statements without the use of AVSLib may well
reach several pages in length.
Naming conventions
AVSLib uses naming conventions in order to divide the large number of functions it provides in separate logical
namespaces, to convey structure information and to aid library's users to reduce their learning curve and avoid
common mistakes.
Note that many of these are just proposals of coding-style conventions; Avisynth script language does not support
separate namespaces, does not distinguishes case, nor it flags name conflicts (instead it resolves them
automatically).
However, it is precisely this lack of protection of identifiers' names which makes necessary a high level of
discipline on behalf of the script writer, in order to avoid masking essential library functionality and the errors that
this masking will inevitably produce.
The naming conventions used throught AVSLib are the following:
• Constants are typed in uppercase. Name components are separated by a single underscore ("_").
• Private functions, variables and constants begin with a double undescore ("__") and are typed in
lowercase. Name components are separated by a single underscore ("_").
• Public functions and variables are typed with each name component capitalised.
• Function arguments are typed in lowercase. Name components are separated by a single underscore ("_").
• Functions and variables related to container types operations have the name of the container type as a
prefix.
• Functions and variables related to common groups of operations typically begin with a prefix derived by
the name of the group (which is usually also the containing module's name). Such is for example the case
for the filters of the edit module.
• All other functions and variables do not have a prefix.

Reserved names
All names begining with the "private" designator (the double underscore at the begining of the name) are
considered reserved. Any future version of AVSLib may freely modify them, delete them, change their semantics,
etc. The list of entities that this rule applies includes:
• Globals (constants and variables).
• Functions
• Function arguments.
Public library constants are also considered reserved in the sense that their value (and associated type) should
remain unaltered by user scripts.

Reserved actions
These include in general all actions that involve messing around with the library's reserved namespace. In
particular, the following rules should be observed, unless you are a library developer or your main objective is to
research curious new bug species:
• Do not directly access private names and never modify their values; if they need to be accessed, a public
function will be provided by the library.
• Never assign a new value to names that are flaged as constants.
• Never pass a reserved argument (one starting with "__") to a library function.
• Do not define variables in the reserved namespace (ie with "__") in your scripts; they may override
library's private functions and/or globals.
Examples

1. Stack clips in a matrix


This script demonstrates the use of arrays for storing clips that will later be processed as a group and also the use
of the Stack() filter, a handy way to quickly create 2D tables of clips.
First the script:
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under the #
terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

# load required modules

LoadModule("avslib", "array", "core")


LoadModule("avslib", "filters", "stack")

# load six clips

vids = ArrayCreate( \
AVISource("file001.avi"), \
AVISource("file002.avi"), \
AVISource("file003.avi"), \
AVISource("file004.avi"), \
AVISource("file005.avi"), \
AVISource("file006.avi") \
)

# stack them in a 2x3 table

return Stack(vids, 2, 3)

The script loads a bunch of clips directly into an array and then passes them to the Stack filter to arrange them in a
2 rows x 3 columns matrix.
Note that there is no restriction that the product (rows x columns) passed to Stack filter must be equal to the
array's length. If it is less, the remaining clips will be discarded; if more, blank clips will be used as padding to fill
the entire matrix.
This is a rather crude method to load sequentially numbered clips; a possible refinement could be like the
following script excerpt:
LoadModule("avslib", "array", "operators")

names = "file001.avi,file002.avi,file003.avi,file004.avi,file005.avi,file006.avi"
vids = names.ArrayOpFunc("AVISource")

or, with just one more line of code, but allowing easier application to other numbers of clips:
LoadModule("avslib", "array", "operators")

Function MakeFName(int idx) { return "file" + String(idx, "%03.0f") + ".avi" }

idxs = ArrayRange(1, 6)
vids = idxs.ArrayOpFunc("MakeFName").ArrayOpFunc("AVISource")

Both refinements however cannot be considered general enough for covering all possible cases. A logical
consequence would be to try and device a generic source function that would deliver an array of clips, given a
path and start / stop indices, like for example the ImageSource standard Avisynth filter does.
The next script does exactly that:
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

# load required modules

LoadModule("avslib", "base", "core")


LoadModule("avslib", "array", "core")
LoadModule("avslib", "array", "operators")
LoadModule("avslib", "array", "slices")
LoadModule("avslib", "filters", "stack")

# Function to load sequentially numbered (.avi) clips

Function ClipSource(string path, int start, int end, int "pad")


{
Assert(start >= 0, "ClipSource: 'start' must be >= 0")
Assert(end >= 0, "ClipSource: 'end' must be >= 0")
pad = Max2(0, Default(pad, 0)) # values <= 0 result in no padding
fmt = "%0" + String(pad) + ".0f"
fname = path + String(start, fmt) + ".avi"
return start <= end \
? ArrayJoin( ArrayCreate(AVISource(fname)), \
ClipSource(path, start + 1, end, pad) ) \
: ""
}

vids = ClipSource("file", 1, 6, 3)

# calculate appropriate rows and columns (as the StackToFit filter does)

vlen = vids.ArrayLen
rows = Round(Sqrt(vlen))
cols = Ceil(Sqrt(vlen))

# reduce size to avoid making the final clip too wide / tall

vids = vids.ArrayOpFunc("ReduceBy2")

# stack them in a rows x cols table

return Stack(vids, rows, cols)

The script loads a couple of additional modules needed by the implementation and then defines ClipSource, the
newly-created generic function for loading arbitrary (.avi only) sources into an array.
ClipSource uses ArrayCreate in order to create a single element array for each recursive invocation and
ArrayJoin for joining the arrays together. That way there is no need to care about the housekeeping of array
elements' delimiters; ArrayJoin takes care of these.
Since ClipSource is a generic function that can return an arbitrary length array, the way to calculate rows and
columns for the matrix should be made generic also. The solution chosen is to use the same equations that are
used by the StackToFit filter; the situation is similar.
Afterwards, the clips are made smaller in order to fit easily in a computer screen (the assumption is that they have
normal video dimensions) by a single call to ArrayOpFunc containing the proper standard Avisynth filter (here
ReduceBy2) and finally they are stacked in the 2D matrix.
Apply a swap transition
This script demonstrates basic use of AVSLib's filters. The example script applies a vertical in-to-out swap
transition between a still photo and a clip. In order to fit things together other filters (resizing, editing and utility)
are also used.
First the script:
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "filters", "edit")


LoadModule("avslib", "filters", "resize")
LoadModule("avslib", "filters", "utility")
LoadModule("avslib", "filters", "animate")

# load a clip and a photo; convert photo to match clp

clpname = "story.avi"
phoname = "photo.jpg"

clp = AVISource(clpname)
ovlap = Round(clp.Framerate / 5)

pho = ImageSource(phoname, start=0, end=2*ovlap-1)


pho = pho.AssumeFPS(clp.Framerate)
pho = pho.ResizeToTarget(clp) # this, coded as is, will do a bilinear resize
pho = pho.ConvertToTarget(clp)
pho = pho.AudioDub(clp)

# create a vertical from-center-to-outside swap transition


# for this we only need to animate size

ph1 = pho.EditTrim(0, ovlap).Amplify(0)


ph2 = pho.EditTrim(ovlap)

black = ph2.BlankClip(color=color_black)
white = ph2.BlankClip(color=color_white)

tmask = LineAnim(black, white, w_start=2, w_end=clp.Width).ScaleToPC()


# add ovlap frames of the stil photo length at the begining

return EditJoin(ph1, \
Overlay(ph2, clp.EditTrim(0, ovlap), mask=tmask), \
clp.EditTrim(ovlap), \
op=EDOP_ALGN)

The script loads an image and converts it to a clip with the same properties as the base story clip. Then it animates
a white over a black mask to create the swap effect and finally combines the parts with EditJoin.
3. Create a simple movie intro clip
This script demonstrates the use of the FilterVarChain filter, which allows to easily chain arbitrary invocations of
a filter with varying arguments. The example creates a simple movie intro clip containing a group of subtitles that
appear in consecutive frames (thus the filter that is chained is SubTitle). The intro clip is then joined with the main
clip.
First the script:
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "filters", "utility")

# load a clip (640x480)


clp = AVISource("script.avi")

# create a CR/LF delimited array of Subtitle parameters (ie a multiline string)


# text, x, y, first_frame, last_frame, font, size, text_color, halo_color, align
#
sub_ttl = \
""" "Smiths Productions", 320, 100, 8, 240,"verdana", 28, color_antiquewhite, color_gray30, 2
"prowdly presents", 320, 140, 32, 240, "verdana", 24, color_antiquewhite, color_gray30, 2
"A John Smith Film", 320, 200, 90, 240, "verdana", 28, color_lavenderblush, color_gray30, 2
"The Family Grows", 320, 280, 150, 240, "verdana", 42, color_lightsalmon, color_gray30, 2
"Episode III", 320, 330, 174, 240, "verdana", 36, color_antiquewhite, color_gray30, 2
"Junior walks!", 320, 400, 198, 240, "verdana", 38, color_lavenderblush, color_gray30, 2"""

sub_tms = "1,1,1,1,1,1"

ttbase = clp.BlankClip(length=240, color=color_gray10)


titles = ttbase.FilterVarChain("SubTitle", sub_tms, sub_ttl)

return Dissolve(titles.Blur(0.5), ttbase.Trim(0, 20), 10) + clp

In order to call the FilterVarChain filter, two arrays must be constructed:


1. The first (sub_ttl in the example) contains the argument lists of each different filter invocation, exactly as
they would be written in an Avisynth script, each on a single line. It is thus a multiline string, a choice that
was made to ease both its readability and its creation.
2. The second (sub_tms in the example) contains the number of times that the filter will be called with the
arguments' settings of each line of the 1st array. Thus, in the example above each subtitle line is called
exactly once.
For more simple cases, where a single group of settings need to be applied many times, the use of FilterChain
filter is recommended.
4. Make a palette clip with all Avisynth named colors
This script demonstrates the array facilities of AVSLib (Stack is also implemented with arrays). The example
creates a color palette (ie a 2D matrix with colored rectangles) from all Avisynth's named colors
The result of running the script is presented below.
Figure 1: Clip produced by example script

Now the script:


# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "array", "core")


LoadModule("avslib", "array", "operators")
LoadModule("avslib", "array", "slices")
LoadModule("avslib", "filters", "stack")

# make an array with all named Avisynth colors (colors_rgb.avsi); white, gray, black
first

colors1 = ArrayCreate( \
color_white, color_gray10, color_gray20, color_gray30, color_gray40, \
color_gray50, color_gray60, color_gray70, color_gray80, color_gray90, \
color_black, color_aliceblue, color_antiquewhite, color_aqua, \
color_aquamarine, color_azure, color_beige, color_bisque, \
color_blanchedalmond, color_blue, color_blueviolet, color_brown, \
color_burlywood, color_cadetblue, color_chartreuse, color_chocolate, \
color_coral, color_cornflowerblue, color_cornsilk, color_crimson, \
color_cyan, color_darkblue, color_darkcyan, color_darkgoldenrod, \
color_darkgray, color_darkgreen, color_darkkhaki, color_darkmagenta, \
color_darkoliveGreen, color_darkorange, color_darkorchid, color_darkred, \
color_darksalmon, color_darkseaGreen, color_darkslateBlue, \
color_darkslateGray, color_darkturquoise, color_darkviolet, \
color_deeppink, color_deepskyblue)

colors2 = ArrayCreate( \
color_dimgray, color_dodgerblue, color_firebrick, color_floralwhite, \
color_forestgreen, color_fuchsia, color_gainsboro, color_ghostwhite, color_gold, \
color_goldenrod, color_gray, color_green, color_greenyellow, color_honeydew, \
color_hotpink, color_indianred, color_indigo, color_ivory, color_khaki, \
color_lavender, color_lavenderblush, color_lawngreen, color_lemonchiffon, \
color_lightblue, color_lightcoral, color_lightcyan, color_lightgoldenrodyellow, \
color_lightgreen, color_lightgrey, color_lightpink, color_lightsalmon, \
color_lightseagreen, color_lightskyblue, color_lightslategray, \
color_lightsteelblue, color_lightyellow, color_lime, color_limegreen, color_linen, \
color_magenta, color_maroon, color_mediumaquamarine, color_mediumblue, \
color_mediumorchid, color_mediumpurple, color_mediumseagreen, \
color_mediumslatenlue, color_mediumspringgreen, color_mediumturquoise, \
color_mediumvioletred)

colors3 = ArrayCreate( \
color_midnightblue, color_mintcream, color_mistyrose, color_moccasin, \
color_navajowhite, color_navy, color_oldlace, color_olive, color_olivedrab, \
color_orange, color_orangered, color_orchid, color_palegoldenrod, \
color_palegoldenrod, color_palegreen, color_paleturquoise, color_palevioletred, \
color_papayawhip, color_peachpuff, color_peru, color_pink, color_plum, \
color_powderblue, color_purple, color_red, color_rosybrown, color_royalblue, \
color_saddlebrown, color_salmon, color_sandybrown, color_seagreen, \
color_seashell, color_sienna, color_silver, color_skyblue, \
color_slateblue, color_slategray, color_snow, color_springgreen, \
color_steelblue, color_tan, color_teal, color_thistle, color_tomato, \
color_turquoise, color_violet, color_wheat, color_whitesmoke, \
color_yellow, color_yellowgreen)

colors = ArrayJoin(colors1, colors2, colors3)

# Create a custom function that returns a clip with the color passed in
Function PaletteCell(int palette_color) {
global color_num = color_num + 1
return BlankClip(color=palette_color, width=60, height=40, length=1 \
).SubTitle(String(color_num), size=12, text_color=color_black,
halo_color=color_gray50)
}

# use colors and custom function to make an array with palette cells clips

global color_num = 0
palette = colors.ArrayOpFunc("PaletteCell")

# Since we have 150 colors we will stack them in a 12x13 = 154 cell grid
# Last 4 cells will be black (empty).
# This will result in a 780x480 clip taking into account the w,h values in custom
function

return Stack(palette, 12, 13)

The script creates an array with all named Avisynth colors (using a combination of the ArrayCreate and
ArrayJoin functions to overcome the 60 arguments limit of Avisynth) and then applies a user-defined function in
each color which returns a clip colored with that color.Finally it calls Stack to stack the colored clips in a 2D
matrix.
5. Load a text file with arbitrary clips
This script demonstrates a way to use the ability offered by AVSLib to change the default array delimiter in order
to create a script that can load and edit non-predefined clips.
The later allows to treat the script as an Avisynth "program" which, in cooperation with a command line driven
encoder (such as Avs2Avi, ffmpeg or VirtualDub plus a Sylia script) can fully automate the related NLE process,
since it will be reduced to a single shell command invocation.
First the script. In this example a call to StackToFit() filter has been used with mode RTF_CROP as an editing
example; more complex tasks are easy to introduce.
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

# load required modules


LoadModule("avslib", "base", "constants")
LoadModule("avslib", "base", "conversion")
LoadPackage("avslib", "array")
LoadModule("avslib", "filters", "stack")

# load a text file containing dir /b output


# surrounded by triple quotes at the start and end of file
dir = Import("files.txt")

# after that dir is an array of filenames!


# but be careful if you hand-type arrays...
ArrayDelimiterSet(CRLF)

# cleanup dir from invalid files (CInt is used to convert true/false to 1/0)
okflag = dir.ArrayOpFunc("Exist").ArrayOpFunc("CInt")
dir = dir.ArrayReduce(okflag)

# read in clips
clp = dir.ArrayOpFunc("DirectShowSource")

# stack them - preserving aspect ratio by cropping - into a 960x640 frame


return StackToFit(clp, 960, 640, RTF_CROP)

As it is apparent from the code, the key aspects of the "trick" presented is
1. to insert triple quotes at the start and end lines of the input file so that Import() will consider the contents
to be an Avisynth string,
2. to change the array delimiter to a CR/LF pair so that each line of the file be treated as an array element.
Because this setup produces an empty initial array element, but also as a safety check since input is unpredictable
because it is not hard-coded into the script anymore, the standard Avisynth function Exist is applied to all script
elements and those where it returns false are removed from the array by ArrayReduce.
Furthermore, since ArrayReduce needs a zero / non-zero "flag" array in order to decide which elements will keep,
the conversion function CInt is applied to the array that resulted from the application of Exist (see the OOP-style
chain at the line assigning to okflag variable) to produce a 0 / 1 value for each false / true value.
The creation of the "files.txt" in the above example can easily be automated with a custom shell script. A working
example (say named "avidir.cmd") is provided below:
@echo off
echo """
for %%f in (%1) do @echo %%~ff
echo """

The shell script takes one (needed) argument, a wildcard specification which can include path information in case
the files are not at the current directory. The script outputs absolute filenames, so that the calling avisynth script
can be located anywhere in the filesystem.
The final step to automate the process is to make another custom shell script (say "makeavi.cmd") that will update
the contents of "files.txt" and (optionally, depending on your needs) invoke the encoder. For example:
@echo off
avidir %1 > files.txt
avs2avi script.avs -l %2

The top level shell script takes the same one (needed) argument, a wildcard specification, as the previous plus an
additional 2nd argument (a filename with the codec settings). It is assumed that the encoder executable is placed at
a folder included in the PATH environment variable.
Thus you can invoke a single shell command in order to import, NLE process and encode a set of clips, such as:
makeavi [wildcard] [codecsettings]

If another encoder is used , the top level script must be modified appropriately to account for the different
command line options needed by the encoder.
6. Create an enhanced movie intro clip
This script extends the third example, demonstrating the animation feautures of AVSLib. The script creates a
movie intro clip containing a group of subtitles that appear and go in consecutive frames with fade-in and fade-out
effects. In addition, subtitles are smoothed to allow a more pleasing view.
First the script:
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "array", "core")


LoadModule("avslib", "filters", "animate")
LoadModule("avslib", "filters", "utility")

# load a clip (640x480)


clp = AVISource("script.avi").ConvertToYV12()

# create a CR/LF delimited array of Subtitle parameters (ie a multiline string)


# text, x, y, first_frame, last_frame, font, size, text_color, halo_color, align
sub_ttl = """ \
"Smiths Productions", 320, 100, 8, 240, "verdana", 28,color_antiquewhite, color_gray30, 2
"prowdly presents", 320, 140, 32, 240, "verdana", 24, color_antiquewhite, \ color_gray30, 2
"A John Smith Film", 320, 200, 90, 240, "verdana", 28,color_lavenderblush, \ color_gray30, 2
"The Family Grows", 320, 280, 150, 240, "verdana", 42, color_lightsalmon, \ color_gray30, 2
"Episode III", 320, 330, 174, 240, "verdana", 36, color_antiquewhite, color_gray30, 2
"Junior walks!", 320, 400, 198, 240, "verdana", 38, color_lavenderblush, color_gray30, 2"""

sub_tms = "1,1,1,1,1,1"

Function FadeSubTitle(clip c, string text, int x, int y, int fs, int fe, \
string font, int size, int tcolor, int hcolor, int align)
{
stmask = c.BlankClip().SubTitle( \
text, x, y, fs, fe, font, size, color_white, color_gray90, align)
stmask = stmask.Blur(1.0).ScaleToPC()
ovl = c.SubTitle(text, x, y, fs, fe, font, size, tcolor, hcolor, align)
frames = ArrayCreate(fs,fs +Round((fe - fs)/5),fe - Round((fe - fs)/5), fe)
opac = "0.1,1,1,0.1"
return PolygonAnim(c, ovl, frames, op_array=opac, mask=stmask)
}
ttbase = clp.BlankClip(length=241, color=color_gray10)
titles = ttbase.FilterVarChain("FadeSubTitle", sub_tms, sub_ttl)

return Dissolve(titles, ttbase.Trim(0, 20), 10) + clp

The new features introduced are contained inside the FadeSubTitle custom filter.
The filter creates a mask of the subtitle's text (with gray halo_color) that it is blured in order to make the fonts
edges fade nicely into the surrounding video. The appearance and disappearance of the subtitle are also faded (in
and out) with the use of the PolygonAnim filter.
As a consequence, the final result is much better than that of the third example.
7. Stack clip frames in a matrix
The purpose of this example script is to create a library routine that stacks a given range of frames of a clip in a
(single clip) matrix. Such an operation offers a way to quick preview a clip, in order for example to search for
scene changes, cut points, etc.
Since we make a library routine we want for it to be generic, ie to support matrices of any dimension and clip
framecounts of any size. How do we proceed to design and implementation then?
At first, one may think to simply Trim signle-frame clips and create an array of the appropriate size to pass
afterwards to the Stack filter. Using recursion this process could be repeated for all the requested frame range.
However this is highly inefficient. To see this let f be the total number of frames to stack and s the frames to stack
in a single output frame. Then the above approach has a startup cost of ceil(f/s) recursive calls to our new function
and setups a filter chain with f Trim's plus ceil(f/s) calls to the Stack filter, which by the way is expensive
(approximately s calls to StackHorizontal / StackVertical per call plus a possible overhead for blank clips creation
plus a startup overhead for operation on arrays). That is f + ceil(f/s)*s ~ 2*f filters.
Fortunately, there is a faster way: the SelectEvery standard Avisynth filter. Thus, instead of trimming and making
arrays every s frames, we make one array of s SelectEvery filters plus s Trim's (because an internal frame range
may be requested) plus a single call to Stack. That is s + s + 1*s ~ 3*s filters. Since typically s << f, we get a
speed increase of orders of magnitude.
A final culprit to deal with is that if the number of frames, f, is not a multiple of s then the last output frame will
contain duplicated frames because some of the s SelectEvery filters will return a shorter by one frame clip, the last
frame of which will show 2 times. To make those frames black (our choice) we must perform some additional
filter operations, which however since we are dealing with one output frame there will be upper-bounded by s.
That is our final filter chain is in the range of [3*s..4*s] filters.
After the above considerations, the implementation of the script is rather straightforward:
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "array", "core")


LoadModule("avslib", "array", "operators")
LoadModule("avslib", "filters", "stack")
Function __select_frames(int ofs, clip c, int total) {
return SelectEvery(c, total, ofs)
}
Function __trim_frames(clip c, int n, int frames, int modulo) {
return n < modulo \
? (frames < c.Framecount ? c.Trim(0, -(frames+1)) : c) \
: c.Trim(0, -frames) + c.BlankClip(length=1)
}
Function StackFrames(clip c, int fstart, int fcount, int rows, int cols)
{
Assert(fstart >= 0, "StackFrames: 'fstart' must be zero or greater")
Assert(fcount > 0, "StackFrames: 'fcount' must be positive")
Assert(rows > 0 && cols > 0, "StackFrames: 'rows', 'cols' must be positive")
nlen = rows * cols
offsets = ArrayRange(fstart, fstart + nlen - 1)
counts = ArrayRange(0, nlen - 1)
old = ArrayDelimiterReset()
extra_args = ArrayCreate(c, nlen)
div = fcount / nlen
mod = fcount % nlen
trim_args = ArrayCreate(div, mod)
old = ArrayDelimiterSet(old)
clips = offsets.ArrayOpFunc("__select_frames", extra_args)
clips = ArrayOpArrayFunc(clips, counts, "__trim_frames", trim_args)
return Stack(clips, rows, cols)
}

# test

clp = BlankClip(length=166, width=632, height=472, color=$000040)


clp = clp.ShowFrameNumber(scroll=true, size=48).AddBorders(4, 4, 4, 4, $ffffff)
clp = clp.Spline16Resize(Round(clp.Width / 4), Round(clp.Height / 4))
return StackFrames(clp, 0, clp.Framecount, 4, 4)
8. Load, convert and join arbitrary clips
This script extends the basic ideas of the fifth example, that is to load arbitrary clips and arguments supplied in
external text files through proper changing of the default AVSLib's array delimiter and process them.
The example script applies moderately complex filtering (resizing, colorspace and fps conversion) based on the
arguments' values and then joins the clips serially in a single timeline.
Shell scripts to automate the creation of the text files as well as the rendering of the .avs script are also provided.
The later allow to treat the script as an Avisynth "program" which, in cooperation with a command line driven
encoder (such as Avs2Avi, ffmpeg or VirtualDub plus a Sylia script) can fully automate complex NLE processes,
reducing them to single shell command invocations.
First the script:
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

# load required modules


LoadModule("avslib", "base", "constants")
LoadModule("avslib", "base", "conversion")
LoadPackage("avslib", "array")
LoadPackage("avslib", "clip")
LoadModule("avslib", "numeric", "rounding")

# load a text file containing dir /b output


# surrounded by triple quotes at the start and end of file
dir = Import("files.txt")

# load two text files containing integers


# (target width and height for the clips in dir)
tw = Import("width.txt")
th = Import("height.txt")

Assert(tw.IsInt && th.IsInt, "Input Error: width or/and height files contain
invalid data")

# after that dir is an array of filenames!


# but be careful if you hand-type arrays...
ArrayDelimiterSet(CRLF)

# cleanup dir from invalid files (CInt is used to convert true/false to 1/0)
okflag = dir.ArrayOpFunc("Exist").ArrayOpFunc("CInt")
dir = dir.ArrayReduce(okflag)

Assert(dir.ArrayLen > 0, \
"Input Error: files.txt does not contain any valid filename")
# read in clips
clp = dir.ArrayOpFunc("DirectShowSource")

# force clip parameters (dimensions, framerate, colorspace) to be the same


# assume all clips are progressive

b_same_fps = (clp.ArrayOpFunc("Framerate").ArrayDistinct().ArrayLen() == 1)
pixel_type = clp.JointPixelType()
fps = clp.JointFPS()

# to assure that target width, height match any clip's colospace


# restrictions we allow for the more restrictive type (yv12)
tw = RoundBs(tw, 4)
th = RoundBs(th, 4)

# now convert clips (resize, convertto..., changefps)


clp = clp.ArrayOpFunc("Spline36Resize", String(tw) + "," + String(th))
clp = clp.ArrayOpFunc("ConvertTo" + pixel_type)
clp = b_same_fps \
? clp \
: clp.ArrayOpFunc("ConvertFPS", String(fps))

# join clips together one after the other, applying Dissolve(c1, c2, 6)
# in each join
return clp.ArraySum(sum_func="Dissolve", sum_args="6")

In the example above a way to auto-convert all supplied clips to compatible characteristics for splicing is
presented.
The core task of clip properties scanning is made by two functions of the clip package: JointPixelType and
JointFPS. The first returns the dominant colorspace of a clip array, while the second the dominant framerate (so
that the fewest conversions result from converting all array's clips to these values).
Based on these values (and also on the user-supplied arguments for the target size) the homogenisation of the
(possibly heterogenuous) clips passed in as arguments is made compactly in just a few lines of code with the use
of array operators (see also the related tutorial). The same is true for the creation of the final combined timeline.
As in the fifth example, the creation of the .txt files can easily be automated with a custom shell script. A working
example for the clips (say named "avidir.cmd") is provided below:
@echo off
echo """
for %%f in (%1) do @echo %%~ff
echo """

The shell script takes one (needed) argument, a wildcard specification which can include path information in case
the files are not at the current directory. The script outputs absolute filenames, so that the calling avisynth script
can be located anywhere in the filesystem.
The final step to automate the process is to make another custom shell script (say "makeavi.cmd") that will update
the contents of the text files and (optionally, depending on your needs) invoke the encoder. For example:
@echo off
avidir %1 > files.txt
echo %2 > width.txt
echo %3 > height.txt
avs2avi script.avs -l %4

The top level shell script takes four arguments, a wildcard specification, two integer values for the width and
heigh and an additional 4th argument (a filename with the codec settings). It is assumed that the encoder
executable is placed at a folder included in the PATH environment variable.
Thus you can invoke a single shell command in order to import, NLE process and encode a set of clips, such as:
makeavi [wildcard] [width] [height] [codecsettings]

If another encoder is used , the top level script must be modified appropriately to account for the different
command line options needed by the encoder.
9. Make an animated draw of a curve with random orbits
This script demonstrates the use of arrays for concurrent drawing of multiple clips (brush strokes) on a base clip,
thus allowing for interesting effects.
The script draws an animated curve with a family of pens, each with a different color and brush (shape). The pens
deviate randomly from the curve's main (x,y) coordinates within a given radius - like the "orbits" setting found in
most modern painting programs - while the curve's main (x,y) coordinates advance constantly on each frame.
The result of running the script up to its last frame is presented below.
Figure 1: Last frame of clip produced by example script (version 1)

Now the script. For reasons of efficiency it uses global canvas-clips for achieving constant draw time per frame.
As a consequence, works by design only on a linear pass from frame 0 to the last. That is if one adds filters at the
end that request random frames back and forth it will not give the intended results.
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "base", "core")


LoadModule("avslib", "array", "core")
LoadModule("avslib", "array", "operators")
LoadModule("avslib", "numeric", "rounding")
LoadModule("avslib", "filters", "utility")
Function ImgSource(string file, clip template, int "target_w", \
int "target_h", int "frames", bool "pc_range")
{
frames = Default(frames, template.Framecount)
target_w = Default(target_w, template.Width)
target_h = Default(target_h, template.Height)
pc_range = Default(pc_range, false)
ret = ImageSource(file, start=0, \
end=frames-1).AssumeFPS(template.Framerate)
ret = ret.ConvertToTarget(template).BilinearResize(target_w, target_h)
return pc_range ? ret.ScaleToPC() : ret
}

Function MakeSolidPen(clip brush, int pen_color) {


return brush.BlankClip(color=pen_color)
}

# create a clip (640x480, 5 sec)


global clp = BlankClip(length=120, color=color_darkslateBlue, \
fps=24, width=640, height=480, pixel_type="YV12")

global pen_canvas = clp.BlankClip(color=color_black, length=1) # pens draw here


global brs_canvas = pen_canvas.ScaleToPC() # brushes draw here

# create solid color brushes


global brushes = ArrayCreate( \
ImgSource("brush1.jpg", clp, 24, 24, pc_range=true), \
ImgSource("brush2.jpg", clp, 24, 24, pc_range=true), \
ImgSource("brush3.jpg", clp, 24, 24, pc_range=true) \
)
colors = "color_gold, color_beige, color_crimson"

global pens = ArrayOpArrayFunc(brushes, colors, "MakeSolidPen")

# define the curves (they assume a 640x480 canvas)


Function NormDist(float x, float m, float s) {
return (1.0/(Sqrt(2*Pi)*s))*Exp(-Pow(x-m,2)/(2*Pow(s,2)))
}

Function SinPulse(float x, float xc, float peak, float spread) {


return peak*NormDist(x, xc, spread)*Sin((x-xc)/(2*Pi))
}

Function Curve(float x) {
return 240 - 120 * Sin(0.65*x*Pi/320) + SinPulse(x, 520, 14000, 120)
}

# Draw on x,y; x belongs to [x_start, x_end)


# assumes brush, bmask have same dimensions
Function DrawItems(clip pen, clip brush, int x_start, int y_start) {
dx = Round(brush.Width / 2.0)
dy = Round(brush.Height / 2.0)
xr = x_start + \
Round(Rand(StrokeRadius*2) - StrokeRadius) # shuffle x,y based on radius
yr = y_start + Round(Rand(StrokeRadius*2) - StrokeRadius)
global pen_canvas = Overlay(pen_canvas, \
pen, x=xr-dx, y=yr-dy, mask=brush, opacity=StrokeOpacity)
global brs_canvas = Overlay(brs_canvas, brush, x=xr-dx, \
y=yr-dy, mask=brush, opacity=StrokeOpacity, \
pc_range=true)
return 1
}
Function DrawCurve(clip c, string curve, int x_start, int x_end, int step)
{
dummy2 = (x_start < x_end && x_start > xlast) ? Eval("""
y_start = Round(Apply(curve, x_start))
dummy = ArrayOpArrayFunc(pens, brushes, "DrawItems", \
String(x_start) + "," + String(y_start))
global xlast = x_start
""") : (x_start <= xlast ? Eval("""
x_start = IntBs(xlast, step) + step
""") : NOP)
return x_start < x_end \
? DrawCurve(c, curve, x_start + step, x_end, step) \
: Overlay(c, pen_canvas, mask=brs_canvas, opacity=1.0,
ignore_conditional=true)
}

# begin draw
global xlast = 0
global xs = 0
global xe = 0
xd = Int(clp.Width / clp.Framecount)
global xdelta = clp.Framecount * xd < clp.Width ? xd + 1 : xd
global StrokeRadius = 20
global StrokeOpacity = 1.0

ScriptClip(clp, """
global xe = Min2(xe + xdelta, last.Width)
DrawCurve(last, "Curve", xs, xe, 4)
""")
ConditionalReader("radius.txt", "StrokeRadius")
ConditionalReader("opac.txt", "StrokeOpacity")
LoadModule("avslib", "base", "core")
LoadModule("avslib", "array", "core")
LoadModule("avslib", "array", "operators")
LoadModule("avslib", "numeric", "rounding")
LoadModule("avslib", "string", "sprintf")
LoadModule("avslib", "filters", "utility")

Function ImgSource(string file, clip template, int "target_w", \


int "target_h", int "frames", bool "pc_range")
{
frames = Default(frames, template.Framecount)
target_w = Default(target_w, template.Width)
target_h = Default(target_h, template.Height)
pc_range = Default(pc_range, false)
ret = ImageSource(file, start=0, \
end=frames-1).AssumeFPS(template.Framerate)
ret = ret.ConvertToTarget(template).BilinearResize(target_w, target_h)
return pc_range ? ret.ScaleToPC() : ret
}

Function MakeSolidPen(clip brush, int pen_color) {


return brush.BlankClip(color=pen_color)
}

# create a clip (640x480, 5 sec)

global clp = BlankClip(length=120, color=color_darkslateBlue, \


fps=24, width=640, height=480, pixel_type="YV12")

global pen_canvas = clp.BlankClip(color=color_black, length=1) # pens draw here


global brs_canvas = pen_canvas.ScaleToPC() # brushes draw here

# create solid color brushes

global brushes = ArrayCreate( \


ImgSource("brush1.jpg", clp, 24, 24, pc_range=true), \
ImgSource("brush2.jpg", clp, 24, 24, pc_range=true), \
ImgSource("brush3.jpg", clp, 24, 24, pc_range=true) \
)
colors = "color_gold, color_beige, color_crimson"

global pens = ArrayOpArrayFunc(brushes, colors, "MakeSolidPen")

# define the curves (they assume a 640x480 canvas)


Function NormDist(float x, float m, float s) {
return (1.0/(Sqrt(2*Pi)*s))*Exp(-Pow(x-m,2)/(2*Pow(s,2)))
}

Function SinPulse(float x, float xc, float peak, float spread) {


return peak*NormDist(x, xc, spread)*Sin((x-xc)/(2*Pi))
}

Function Curve(float x) {
return 240 - 120 * Sin(0.65*x*Pi/320) + SinPulse(x, 520, 14000, 120)
}

Up to this point the script loads required modules and declares the curve-generating functions and a utility
function - ImgSource - that loads an image and converts it to a clip with the same characteristics as a template
clip. In addition it creates the arrays with pens and brushes that will be used for drawing.
Because here different brush shapes and pen colors are drawn, the script uses two global canvas-like clips to hold
brush strokes of the previous frames. One for the actual color (pen) strokes and one for the opacity mask (brush)
strokes.
The actual drawing part of the script code follows:
# Draw on x,y; x belongs to [x_start, x_end)
# assumes brush, bmask have same dimensions
Function DrawItems(clip pen, clip brush, int x_start, int y_start) {
dx = Round(brush.Width / 2.0)
dy = Round(brush.Height / 2.0)
# shuffle x,y based on radius
xr = x_start + Round(Rand(StrokeRadius*2) - StrokeRadius)
yr = y_start + Round(Rand(StrokeRadius*2) - StrokeRadius)
global pen_canvas = Overlay(pen_canvas, pen, x=xr-dx, \
y=yr-dy, mask=brush, opacity=StrokeOpacity)
global brs_canvas = Overlay(brs_canvas, brush, x=xr-dx, \
y=yr-dy, mask=brush, opacity=StrokeOpacity, \
pc_range=true)
return 1 # return value doesn't really matters
}

Function DrawCurve(clip c, string curve, int x_start, int x_end, int step)
{
dummy2 = (x_start < x_end && x_start > xlast) ? Eval("""
y_start = Round(Apply(curve, x_start))
dummy = ArrayOpArrayFunc(pens, brushes, "DrawItems", \
String(x_start) + "," + String(y_start))
global xlast = x_start
""") : (x_start <= xlast ? Eval("""
x_start = IntBs(xlast, step) + step
""") : NOP)
return x_start < x_end \
? DrawCurve(c, curve, x_start + step, x_end, step) \
: Overlay(c, pen_canvas, mask=brs_canvas, opacity=1.0, \
ignore_conditional=true)
}

The heart of the drawing procedure is DrawItems, which is called by ArrayOpArrayFunc for every defined pen-
brush pair. The caller simply ensures that drawing occures only after the last x-point processed by the previous
frames and, at the end of the recursion, overlays the pens' canvas on top of the base clip, using the brushes' canvas
as a mask.
The if...elseif..else block inside DrawCurve (implemented with Eval and triply quoted strings) is used to quickly
advance x_start in one step and avoid the cost of unneeded recursive function calls. IntBs(xlast, step) ensures that
x_start will remain a multiple of step.
# begin draw
global xlast = 0
global xs = 0
global xe = 0
xd = Int(clp.Width / clp.Framecount)
global xdelta = clp.Framecount * xd < clp.Width ? xd + 1 : xd
global StrokeRadius = 20
global StrokeOpacity = 1.0

ScriptClip(clp, """
global xe = Min2(xe + xdelta, last.Width)
DrawCurve(last, "Curve", xs, xe, 4)
""")
ConditionalReader("radius.txt", "StrokeRadius")
ConditionalReader("opac.txt", "StrokeOpacity")

The rest of the code is simply the setup of global variables needed for proper execution and the actual calls to
ScriptClip and ConditionalReader.
The later is to allow the radius and opacity of the pen strokes to be controlled by external files; this gives greater
flexibility for determining the final shape of the pen strokes. The links following give the specific files used in this
example: i.radius.txt and ii.opac.txt.
The assignment to xe global is used to advance the pen strokes towards the right of the clip on each frame. It could
be done in a separate FrameEvaluate call, but also in a separate line of the script passed to SriptClip (with triple
quotes) as well. Here the later is selected for no special reason.
As is the case always, there is space for improvement in the script; the next example script, version 2 introduces
improvements regarding the loading of brushes and pens by creating more generic and easy to adapt code.
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "base", "core")


LoadModule("avslib", "array", "core")
LoadModule("avslib", "array", "operators")
LoadModule("avslib", "numeric", "rounding")
LoadModule("avslib", "filters", "utility")

Function ImgSource(string file, clip template, int "target_w", \


int "target_h", int "frames", bool "pc_range")
{
frames = Default(frames, template.Framecount)
target_w = Default(target_w, template.Width)
target_h = Default(target_h, template.Height)
pc_range = Default(pc_range, false)
ret = ImageSource(file, start=0, \
end=frames-1).AssumeFPS(template.Framerate)
ret = ret.ConvertToTarget(template).BilinearResize(target_w, target_h)
return pc_range ? ret.ScaleToPC() : ret
}

Function MakeSolidPen(clip brush, int pen_color) {


return brush.BlankClip(color=pen_color)
}

# create a clip (640x480, 5 sec)

global clp = BlankClip(length=120, color=color_darkslateBlue, \


fps=24, width=640, height=480, pixel_type="YV12")

global pen_canvas = clp.BlankClip(color=color_black, length=1) # pens draw here


global brs_canvas = pen_canvas.ScaleToPC() # brushes draw here

# create solid color brushes


Function LoadBrush(int idx, clip tpl, int w, int h) {
fname = "brush" + String(idx) + ".jpg"
return ImgSource(fname, tpl, w, h, pc_range=true)
}
global brushes = ArrayRange(1, 6).ArrayOpFunc("LoadBrush", "clp, 24, 24")

colors = "color_gold, color_beige, color_crimson, color_forestgreen,


color_lightskyblue, color_firebrick"
global pens = ArrayOpArrayFunc(brushes, colors, "MakeSolidPen")

# define the curves (they assume a 640x480 canvas)


Function NormDist(float x, float m, float s) {
return (1.0/(Sqrt(2*Pi)*s))*Exp(-Pow(x-m,2)/(2*Pow(s,2)))
}
Function SinPulse(float x, float xc, float peak, float spread) {
return peak*NormDist(x, xc, spread)*Sin((x-xc)/(2*Pi))
}
Function Curve(float x) { return 240 - 120 * Sin(0.65*x*Pi/320) + \
SinPulse(x, 520, 14000, 120) }

# Draw on x,y; x belongs to [x_start, x_end)


# assumes brush, bmask have same dimensions
Function DrawItems(clip pen, clip brush, int x_start, int y_start) {
dx = Round(brush.Width / 2.0)
dy = Round(brush.Height / 2.0)
# shuffle x,y based on radius
xr = x_start + Round(Rand(StrokeRadius*2) - StrokeRadius)
yr = y_start + Round(Rand(StrokeRadius*2) - StrokeRadius)
global pen_canvas = Overlay(pen_canvas, pen, x=xr-dx, y=yr-dy, \
mask=brush, opacity=StrokeOpacity)
global brs_canvas = Overlay(brs_canvas, brush, x=xr-dx, y=yr-dy, \
mask=brush, opacity=StrokeOpacity, \
pc_range=true)
return 1
}

Function DrawCurve(clip c, string curve, int x_start, int x_end, int step)
{
dummy2 = (x_start < x_end && x_start > xlast) ? Eval("""
y_start = Round(Apply(curve, x_start))
dummy = ArrayOpArrayFunc(pens, brushes, "DrawItems", \
String(x_start) + "," + String(y_start))
global xlast = x_start
""") : (x_start <= xlast ? Eval("""
x_start = IntBs(xlast, step) + step
""") : NOP)
return x_start < x_end \
? DrawCurve(c, curve, x_start + step, x_end, step) \
: Overlay(c, pen_canvas, mask=brs_canvas, \
opacity=1.0, ignore_conditional=true)
}
# begin draw
global xlast = 0
global xs = 0
global xe = 0
xd = Int(clp.Width / clp.Framecount)
global xdelta = clp.Framecount * xd < clp.Width ? xd + 1 : xd
global StrokeRadius = 20
global StrokeOpacity = 1.0

ScriptClip(clp, """
global xe = Min2(xe + xdelta, last.Width)
DrawCurve(last, "Curve", xs, xe, 4)
""")
ConditionalReader("radius.txt", "StrokeRadius")
ConditionalReader("opac.txt", "StrokeOpacity")

he result of running the modified script up to its last frame is presented below.
Figure 2: Last frame of clip produced by example script (version 2)

The differences with the first version are briefly outlined below.
# create solid color brushes

Function LoadBrush(int idx, clip tpl, int w, int h) {


fname = "brush" + String(idx) + ".jpg"
return ImgSource(fname, tpl, w, h, pc_range=true)
}

global brushes = ArrayRange(1, 6).ArrayOpFunc("LoadBrush", "clp, 24, 24")

colors = "color_gold, color_beige, color_crimson, color_forestgreen, " + \


"color_lightskyblue, color_firebrick"

Brushes are loaded by a custom function that calculates the filename based on an index. This allows to load a
sequence of brushes with a simple ArrayRange call followed by ArrayOpFunc generated calls to the custom
function in the same script line, thanks to OOP notation.
Here since clp is a global we simply pass its name to the LoadBrush's arguments inside ArrayOpFunc call; else (if
clp was not a global) we would have to use either ArrayCreate(clp) or StrPrint("%g", clp) to create a global and
get its name as a string.
The colors array is updated also, to accommodate for the three new brushes used: brush4.jpg, brush5.jpg and
brush6.jpg.
10. Loop through filter settings
This script demonstrates the use of the array facilities of AVSLib in order to produce comprehensive previews of
the result of varying combinations of a filter's settings to a source clip.
In addition, the script demonstrates the debug logging facilities of AVSLib.
The example script applies a set of different filtering parameters combinations to a single (reference) frame of a
clip and then joins the filtered frames into a single clip. The coding is such that one can easily modify the loop
parameters, for example to make a second fine-grained pass of the most promissing subset of parameters
combinations.
First the script:
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "array", "core")


LoadModule("avslib", "array", "operators")
LoadModule("avslib", "array", "slices")
LoadModule("avslib", "array", "functions")

# use a log file to quickly verify the correctness of looping through indices

LoadModule("avslib", "debug", "logging")

SetDebugFile("__log__.txt")
SetDebugMode(DBG_LEVEL_1) # use DBG_NODEBUG to de-activate logging

# load a reference frame clip

global ref = AVISource("reference.avi").Trim(150, -1)

# in this example the filter to loop through is Levels

# 4*3*4*3*3 = 432 frames


global l1 = "0,40,80,120" # input_low
global l2 = "0.75,1.0,1.5" # gamma
global l3 = "255,210,165,120" # input_high
global l4 = "0,80,160" # output_low
global l5 = "255,190,120" # output_high

total_loops = 5
global loop_counts = "4,3,4,3,3"

Function LoopDiv(int idx, string loop_cnt) {


subrange = loop_cnt.ArrayGetRange(idx)
return subrange.ArrayLen > 0 ? subrange.ArrayProduct() : 1
}

total_steps = loop_counts.ArrayProduct()
global loop_ids = ArrayRange(1, total_loops)
global loop_divs = ArrayOpFunc(loop_ids, "LoopDiv", "loop_counts")

Function GetLoopIndex(int lid, int frame) {


lcnt = loop_counts.ArrayGet(lid - 1)
ldiv = loop_divs.ArrayGet(lid - 1)
return (frame / ldiv) % lcnt
}

Function GetLoopValue(int loop_id, int index) {


return Eval("l" + String(loop_id) + ".ArrayGet(" + String(index) + ")")
}

Function ApplyFilter(int frame)


{
indices = ArrayOpFunc(loop_ids, "GetLoopIndex", String(frame))
values = ArrayOpArrayFunc(loop_ids, indices, "GetLoopValue")

DebugLog(DBG_LEVEL_1, (frame == 0 ? "Processing frames:\n" : "") + \


"\tframe = %i\tindices = %s\tvalues = %s", frame, indices, values)

# In this example all filter's arguments are contained in 'values' array, so


# constructing the command line is particularly easy; if named arguments are
# wanted, use StrPrint() or ArrayGetString()
ret = Eval("ref.Levels(" + values + ")")
return ret.SubTitle(values)
}
DebugLog(DBG_LEVEL_1, "Starting filter looping\n\tloop_ids = \
%s\n\tloop_divs = %s", loop_ids, loop_divs)
return ScriptClip(ref.Loop(total_steps), "ApplyFilter(current_frame)")

In order to speed-up the script's execution (previews must be fast) the script does not go through the creation of a
combined array of all possible parameters combinations and then a series of trims.
Instead, the combinations are calculated on-the-fly for each frame inside a custom function, which is fed to
ScriptClip. The above design uses small array sizes and a much smaller filter chain, thus offering increased
performance.
A call to DebugLog inside the conditional environment function (ApplyFilter) prints out a nice log of all the
loops' values to assist the script developer in confirming the correct operation of the script. The calls to
SetDebugFile and SetDebugMode indicate where (the log's filename) and what will be logged (DebugLog will
not print anything if its first argument is less than the one passed to SetDebugMode).
11. Loop through filter settings - revisited
This script demonstrates the use of the array facilities of AVSLib in order to produce comprehensive previews of
the result of varying combinations of a filter's settings to a source clip.
The script builds upon the previous example, extending it to demonstrate how it is possible to preview more
complex filters, possibly with named arguments and / or temporal characteristics.
In addition, as in the previous example the script demonstrates the debug logging facilities of AVSLib.
The example script applies a set of different filtering parameters combinations to a single (reference) subrange of
a clip and then joins the filtered clips into a single clip. The coding is such that one can easily modify the loop
parameters, for example to make a second fine-grained pass of the most promissing subset of parameters
combinations.
In addition the script stacks horizontally side-by-side the filtered and original clip to allow for easy review of the
filter's effect. For large clips this means that you will need a wide screen display or to modify the script such that
only an area of interest is selected (for example using Crop).
Now the script:
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "array", "core")


LoadModule("avslib", "array", "operators")
LoadModule("avslib", "array", "slices")
LoadModule("avslib", "array", "functions")

# use a log file to quickly verify the correctness of looping through indices
LoadModule("avslib", "debug", "logging")

SetDebugFile("__log__.txt")
SetDebugMode(DBG_LEVEL_1) # use DBG_NODEBUG to de-activate logging

# load filter-specific modules (assumes they are at the same folder as the script)

LoadPlugin("MaskTools.dll")
LoadPlugin("RemoveGrain.dll")
LoadPlugin("Repair.dll")
Import("SeeSaw.avs")

# load a reference clip

global ref = AVISource("reference.avi").Trim(98, -8).Spline36Resize(480, 360)


global ref_frames = ref.Framecount
# in this example the filter to loop through is SeeSaw
# 3*3*3*3*3*3*3 = 2187 blocks * 8 frames = 17496 frames
global l1 = "2,4,6" # NRlimit
global l2 = "3,5,7" # NRlimit2
global l3 = "1.3,1.5,1.7" # Sstr
global l4 = "20,24,28" # SdampHi
global l5 = "42,49,56" # bias
global l6 = "42,49,56" # sootheT
global l7 = "0,2,4" # sootheS

total_loops = 7
global loop_counts = "3,3,3,3,3,3,3"

Function LoopDiv(int idx, string loop_cnt) {


subrange = loop_cnt.ArrayGetRange(idx)
return subrange.ArrayLen > 0 ? subrange.ArrayProduct() : 1
}

total_steps = loop_counts.ArrayProduct()
global loop_ids = ArrayRange(1, total_loops)
global loop_divs = ArrayOpFunc(loop_ids, "LoopDiv", "loop_counts")

Function GetLoopIndex(int lid, int frame) {


lcnt = loop_counts.ArrayGet(lid - 1)
ldiv = loop_divs.ArrayGet(lid - 1)
return ((frame / ref_frames) / ldiv) % lcnt # int divisions; remainder is
trunced
}

Function GetLoopValue(int loop_id, int index) {


return Eval("l" + String(loop_id) + ".ArrayGet(" + String(index) + ")")
}

Function ApplyFilter(int frame)


{
indices = ArrayOpFunc(loop_ids, "GetLoopIndex", String(frame))
values = ArrayOpArrayFunc(loop_ids, indices, "GetLoopValue")

DebugLog(DBG_LEVEL_1, (frame == 0 ? "Processing frames:\n" : "") + \


"\tframe = %i\tblock = %i\tindices = %s\tvalues = %s", frame, \
(frame / ref_frames), indices, values)
# In this example filter's arguments are named, so constructing the command line
# is a bit more tricky

cmdline = "SeeSaw(ref, NRlimit=" + values.ArrayGetString(0) + \


", NRLimit2=" + values.ArrayGetString(1) + \
", Sstr=" + values.ArrayGetString(2) + \
", sdampHi=" + values.ArrayGetString(3) + \
", bias=" + values.ArrayGetString(4) + \
", sootheT=" + values.ArrayGetString(5) + \
", sootheS=" + values.ArrayGetString(6) + \
")"
# run the filter; stack with the original for immediate comparison
ret = Eval(cmdline)
# we tream after evaluating the filter, in order for the correct frame
#to be returned
return StackHorizontal( \
ret.Trim(frame % ref_frames, -1).SubTitle(cmdline, size=12, \
text_color=color_white, halo_color=color_gray20), \
ref.Trim(frame % ref_frames, -1).SubTitle("Original", size=12, \
text_color=color_white, halo_color=color_gray20))
}

DebugLog(DBG_LEVEL_1, "Starting filter looping\n\tloop_ids = %s\n\tloop_divs = \


%s", loop_ids, loop_divs)

# in order for stackhorizontal to work, must stack here also


clp = ref.Loop(total_steps)
return ScriptClip(StackHorizontal(clp, clp), "ApplyFilter(current_frame)")

As it is apparent from the code, the overall structure of the previous example script is retained. However, in order
to achieve the new functionality a number of changes are made, notably the following:
• The filter-invocation command is constructed with ArrayGetString() due to the need to assign to named
arguments.
ArrayGetString is handy for that purposes because it directly returns the proper string representation of
the array element (except of quoting of string values; in that case one must use StrQuote() afterwards).
• The frame number is divided with reference clip's total frames in GetLoopIndex in order to access the
correct index settings for each frame.
• ret and ref clips are trimmed (frame mod ref.Framecount) on each frame in order to achieve the
"recycling" of the reference clip in the whole frame sequence.
The above skeleton can be adopted for more elaborate tasks also, with minor changes. For example, one can crop
the reference clip before passing it to the conditional environment in order to focus on a specific area of the clip.
Or, if a number of filtering operations is desired in one pass, one can write a custom function that will accept an
array of values and will call the appropriate filters in sequence.
12. Load, convert and join with transition effect arbitrary clips
This script extends the basic ideas of the fifth and eighth examples. It applies a moderately complex filtering
sequence (resizing and colorspace and fps conversion) based on the arguments' values and also joins the clips
serially in a single timeline applying a relatively complex transition effect.
Shell scripts to automate the creation of the text files as well as the rendering of the .avs script are also provided.
The later allow to treat the script as an Avisynth "program" which, in cooperation with a command line driven
encoder (such as Avs2Avi, ffmpeg or VirtualDub plus a Sylia script) can fully automate complex NLE processes,
reducing them to single shell command invocations.
First the script. The transition code is contained first, followed by the same clips' importing and filtering section
that was presented at the eighth example. The last lines of the script are different though, to allow the more
complex joining process that this example demonstrates.
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

# load required modules


LoadModule("avslib", "base", "constants")
LoadModule("avslib", "base", "conversion")
LoadPackage("avslib", "array")
LoadPackage("avslib", "clip")
LoadModule("avslib", "numeric", "rounding")
LoadModule("avslib", "string", "search")
LoadModule("avslib", "filters", "edit")
LoadModule("avslib", "filters", "stack")

# transition code
Function Crop4x4(int i, clip c) {
cw = Round(c.Width / 4)
ch = Round(c.Height / 4)
row = Int(i / 4) # [0..3]
col = i % 4 # [0..3]
return c.Crop(col * cw, row * ch, cw, ch, true)
}
# Using a single underscore is a good convention for private user globals;
# they do not clash with AVSLib namespace
global _crop_clip = BlankClip(length=0)
Function ClipDivide4x4(clip base) {
loop = ArrayRange(0, 15, step=1)
global _crop_clip = base
return ArrayOpFunc(loop, "Crop4x4", "_crop_clip")
}
# assume each subclip is 15 frames long; appear is a flags array
global _fade_count = 0

# either blanks clip c or leaves it unchanged, depending on value of flag


Function _ovl_clip5(clip c, val aflag) {
return aflag > 0 ? c : c.BlankClip()
}
Function FadeSubClip(clip subclip, string appear) {
ap = ArraySplit(appear, _fade_count, chunksize=5)
# increase counter so that next call process next subclip
global _fade_count = _fade_count + 1
# split subclip to 5 pieces
ac = ArrayCreate( \
subclip.EditTrim(0, 3), \
subclip.EditTrim(3, 6), \
subclip.EditTrim(6, 9), \
subclip.EditTrim(9, 12), \
subclip.EditTrim(12, 15) \
)
# blank subclip in all parts where ap has zeros and recombine pieces
video = ArrayOpArrayFunc(ac, ap, "_ovl_clip5").ArraySum()
# keep audio from original clip to maintain precision
return AudioDub(video, subclip)
}

# Creates a vanishing / appearing checkboard transition effect.


# Since we will use the function with EditJoin we know that there always be
# two clip arguments.
Function Transition(clip c1, clip c2) {
start = c1.EditTrim(0, -8) # all but last 8
ef1 = c1.EditTrim(-8) # last 8
ef2 = c2.EditTrim(0, 7) # first 7
end = c2.EditTrim(7) # all but first 7

# divide effect clips to a matrix of 4x4 subclips, each with 15


# frames & merge (+)
cr = ArrayOpArray(ef1.ClipDivide4x4(), ef2.ClipDivide4x4(), "+")

# create subclip appearence flag arrays, one for each 3 frames


# (5 steps total) in each step make 4 subclips to dissapear for
# ef1 and 4 to apear for ef2
b1 = "1,1,0,1, 0,1,1,1, 1,0,1,1, 1,1,1,0"
b2 = "1,1,0,1, 0,0,1,0, 1,0,0,1, 0,1,1,0"
b3 = "0,0,0,1, 1,0,0,0, 0,0,0,1, 0,0,1,0"
b4 = "0,0,1,1, 1,0,1,0, 0,1,0,1, 1,0,1,0"
b5 = "1,0,1,1, 1,1,1,0, 0,1,0,1, 1,1,1,1"
# multiplex flag arrays in order to create continuous blocks of flags
# (ie the columns of the table above) for each subclip
appear = ArrayPlex(b1, b2, b3, b4, b5)
global _fade_count = 0
crf = ArrayOpFunc(cr, "FadeSubClip", StrQuote(appear))
trans = Stack(crf, 4, 4)
return start + trans + end
}
# load a text file containing dir /b output
# surrounded by triple quotes at the start and end of file
dir = Import("files.txt")

# load two text files containing integers


# (target width and height for the clips in dir)
tw = Import("width.txt")
th = Import("height.txt")

Assert(tw.IsInt && th.IsInt, \


"Input Error: width or/and height files contain invalid data")
# after that dir is an array of filenames!
# but be careful if you hand-type arrays... (see the transition code block)
ArrayDelimiterSet(CRLF)

# cleanup dir from invalid files (CInt is used to convert true/false to 1/0)
okflag = dir.ArrayOpFunc("Exist").ArrayOpFunc("CInt")
dir = dir.ArrayReduce(okflag)

Assert(dir.ArrayLen > 0, \
"Input Error: files.txt does not contain any valid filename")
# read in clips
clp = dir.ArrayOpFunc("DirectShowSource")

# force clip parameters (dimensions, framerate, colorspace) to be the same


# assume all clips are progressive
b_same_fps = (clp.ArrayOpFunc("Framerate").ArrayDistinct().ArrayLen() == 1)
pixel_type = clp.JointPixelType()
fps = clp.JointFPS()

# to assure that target width, height match any clip's colospace


# restrictions we allow for the more restrictive type (yv12)
tw = RoundBs(tw, 4)
th = RoundBs(th, 4)
# now convert clips (resize, convertto..., changefps)
clp = clp.ArrayOpFunc("Spline36Resize", String(tw) + "," + String(th))
clp = clp.ArrayOpFunc("ConvertTo" + pixel_type)
clp = b_same_fps \
? clp \
: clp.ArrayOpFunc("ConvertFPS", String(fps))
# restore now default array delimiter, in order for transition code to work
# restore also delimiters inside clp (a simple strreplace op.)
old = ArrayDelimiterReset()
clp = StrReplace(clp, old, ",")

# join clips together one after the other, applying EditJoin with
# custom user function (our transition) in each join
# we cannot pass a quoted string to sum_args (even with three double quotes),
# so we assign the string to a global and pass in the global's name unquoted
global _tr_func = "Transition"
return clp.ArraySum(sum_func="EditJoin", sum_args="op=EDOP_USER, \
extra_info=_tr_func")

In the example above the script first loads and auto-convert all supplied clips to compatible characteristics for
splicing. See examples five and eight for details.
Afterwards, the now homogenised clips are integrated together with EditJoin in just a single line of code, thanks
to the array operators facilities of AVSLib (see the related tutorial for a more in-depth presentation).
The transition filter is passed in as a global, because quoted arguments do not work well inside ArraySum.
Although this is a hack it does not hurt to do so, since globals will always be evaluated correctly even when this
limitation will eventually be arised at the future.
As in the fifth and eighth examples, the creation of the .txt files can easily be automated with a custom shell script.
A working example regarding the clips (say named "avidir.cmd") is provided below:
@echo off
echo """
for %%f in (%1) do @echo %%~ff
echo """

The shell script takes one (needed) argument, a wildcard specification which can include path information in case
the files are not at the current directory. The script outputs absolute filenames, so that the calling avisynth script
can be located anywhere in the filesystem.
The final step to automate the process is to make another custom shell script (say "makeavi.cmd") that will
update the contents of the text files and (optionally, depending on your needs) invoke the encoder. For example:
@echo off
avidir %1 > files.txt
echo %2 > width.txt
echo %3 > height.txt
avs2avi script.avs -l %4

The top level shell script takes four arguments, a wildcard specification, two integer values for the width and
heigh and an additional 4th argument (a filename with the codec settings). It is assumed that the encoder
executable is placed at a folder included in the PATH environment variable.
Thus you can invoke a single shell command in order to import, NLE process and encode a set of clips, such as:
makeavi [wildcard] [width] [height] [codecsettings]

If another encoder is used , the top level script must be modified appropriately to account for the different
command line options needed by the encoder.
13. Multi-color mask creation and manipulation
This example script creates combined colormasks of multiple colors and manipulates them in various ways. To
demonstrate the applicability of color mask selection to moving objects, an animated source is constructed using
the animation filters supplied by AVSLib.
First the script. In this example, colors are provided as R,G,B triplets in decimal, as it is common to show up in
image editing applications. Typically in real video editing this will be the most convenient way to specify color
values, since the values will have been read inside an image editing application from a group of sample frames of
the video.
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadPackage("avslib", "array")
LoadModule("avslib", "clip", "core")
LoadModule("avslib", "filters", "stack")
LoadModule("avslib", "filters", "animate")
LoadModule("avslib", "filters", "utility")
LoadPlugin("mt_masktools.dll")

# ------ create a source ---------


clp = BlankClip(pixel_type="YUY2", length=401)
clp = Overlay(clp, clp.BlankClip(color=color_red, width=100, height=100), \
x=100, y=100)
clp = Overlay(clp, clp.BlankClip(color=color_green, width=100, height=100), \
x=200, y=200)
clp = Overlay(clp, clp.BlankClip(color=color_blue, width=100, height=100), \
x=300, y=100)
clp = Overlay(clp, clp.BlankClip(color=color_magenta, width=100, height=100), \
x=300, y=300)
f = ArrayRange(0,400,50)
x = "0,120,240,120,0,120,240,120,0"
y = "0,80,0,-100,0,80,0,-100,0"
x = x.ArrayOpValue(Round(clp.Width / 2), "+")
y = y.ArrayOpValue(Round(clp.Height / 2), "+")

clp = clp.BlankClip().PolygonAnim(clp, f, x, y)
clp = clp.ConvertToRGB32.ResetMask()

# ------ apply color masks ---------


Function _to_RGB(string colors) {
old = ArrayDelimiterReset
ret = MakeRGBColor(colors.ArrayGet(0), colors.ArrayGet(1), \
colors.ArrayGet(2))
old = ArrayDelimiterSet(old)
return ret
}
Function _make_mask(int color, clip c) {
return c.ColorKeyMask(color, 20).ShowAlpha().Invert()
}
mask_colors = "255,0,0|0,128,0|0,0,255|255,0,255"

old = ArrayDelimiterSet("|")
colors = mask_colors.ArrayOpFunc("_to_RGB")
cmasks = colors.ArrayOpFunc("_make_mask", ArrayCreate(clp))

# quoted strings inside sum_args do not work; workaround with a global


global mode = "or"
msk = cmasks.ArraySum("ConvertToYV12", sum_func="mt_logic", sum_args="mode")
msk_if = msk.FilterChain("mt_inflate", 6, "u=2, v=2" \
).FilterChain("Blur", 100, "1.25" \
).FilterChain("mt_deflate", 6, "u=2, v=2")
rst = Overlay(clp, clp.BlankClip(color=color_gold), mask=msk, opacity=0.4)

StackToFit( \
ArrayCreate(clp, msk.ConvertToRGB32, msk_if.ConvertToRGB32, rst), \
4*240, 3*240)

Now look at the code


LoadPackage("avslib", "array")
LoadModule("avslib", "clip", "core")
LoadModule("avslib", "filters", "stack")
LoadModule("avslib", "filters", "animate")
LoadModule("avslib", "filters", "utility")
LoadPlugin("mt_masktools.dll")
# ------ create a source ---------
clp = BlankClip(pixel_type="YUY2", length=401)
clp = Overlay(clp, clp.BlankClip(color=color_red, width=100, height=100), \
x=100, y=100)
clp = Overlay(clp, clp.BlankClip(color=color_green, width=100, height=100), \
x=200, y=200)
clp = Overlay(clp, clp.BlankClip(color=color_blue, width=100, height=100), \
x=300, y=100)
clp = Overlay(clp, clp.BlankClip(color=color_magenta, width=100, height=100), \
x=300, y=300)
f = ArrayRange(0,400,50)
x = "0,120,240,120,0,120,240,120,0"
y = "0,80,0,-100,0,80,0,-100,0"
x = x.ArrayOpValue(Round(clp.Width / 2), "+")
y = y.ArrayOpValue(Round(clp.Height / 2), "+")
clp = clp.BlankClip().PolygonAnim(clp, f, x, y)
clp = clp.ConvertToRGB32.ResetMask()
Up to this point the script loads needed modules and plugins and constructs its animated source. This consists of a
blank clip on top of which four colored rectangles are overlayed. The clip then is moved in a polygonal line such
that the area occupied by the rectangles seems to collide and jump back from the borders of the clip like a particle
in a box.
f, x, and y correspond to frame number, x position and y position of the moving clip. The call to ArrayOpValue is
made to translate the x and y coordinates from the top-left corner of the clip to its center, as needed by the
PolygonAnim filter.
# ------ apply color masks ---------
Function _to_RGB(string colors) {
old = ArrayDelimiterReset()
ret = MakeRGBColor(colors.ArrayGet(0), colors.ArrayGet(1), \
colors.ArrayGet(2))
old = ArrayDelimiterSet(old)
return ret
}
Function _make_mask(int color, clip c) {
return c.ColorKeyMask(color, 20).ShowAlpha().Invert()
}
mask_colors = "255,0,0|0,128,0|0,0,255|255,0,255"

old = ArrayDelimiterSet("|")
colors = mask_colors.ArrayOpFunc("_to_RGB")
cmasks = colors.ArrayOpFunc("_make_mask", ArrayCreate(clp))
# quoted strings inside sum_args do not work; workaround with a global
global mode = "or"
msk = cmasks.ArraySum("ConvertToYV12", sum_func="mt_logic", sum_args="mode")
msk_if = msk.FilterChain("mt_inflate", 6, "u=2, v=2" \
).FilterChain("Blur", 100, "1.25" \
).FilterChain("mt_deflate", 6, "u=2, v=2")
rst = Overlay(clp, clp.BlankClip(color=color_gold), mask=msk, opacity=0.4)

StackToFit( \
ArrayCreate(clp, msk.ConvertToRGB32, msk_if.ConvertToRGB32, rst), \
4*240, 3*240)

To create the colors from the decimal R,G,B triplets a custom function is used that expects an array of RGB color
triplets with the default (comma) array delimiter; the function then calls the MakeRGBColor to do the actual
work. Current array delimiter is stored and restored before leaving the function, a practise that must be followed
by any function that expects an array with a specific delimiter.
The colors array is then passed to _make_mask custom function to create the array of separate color masks.
Because we want to act on what is inside the mask (ie we want to operate on masked colors and not to protect
them) the Invert standard Avisynth filter is used inside _make_mask.
The separate mask clips are then summed up with mt_logic using "or" mode, with a call to ArraySum. Because
mt_logic accepts only YV12 input, ConvertToYV12 is used as the elm_func argument of ArraySum to make the
conversion.
The combined mask is then proccessed, with a series of calls to mt_inflate, Blur and mt_deflate filters,
conveniently grouped in just a few lines through the use of the FilterChain filter. This is just to demonstrate the
possibilities offered by AVSLib for irregular color key masks manipulations; here since our masked shape is
highly regular the initial mask is better suited for subsequent operations.
Finally a simple color transformation of the source clip (color shift) is performed using the created mask. The
original and modified clips along with the masks are stacked together in a specified frame size with the help of the
StackToFit filter
14. Create an expanding rotating circle of rotating stars
This series of examples script demonstrates the (large) improvement in capacity and speed of the animation
filters supplied by AVSLib in version 1.1.0, compared to previous versions.
The first example script performs the same animation as the sixth animation example of version's 1.0.0
documentation - that is twelve rectangles that move spirally from the center to the border of the screen while in
parallel they enlarge and overlayed in each animation interval with a different overlay mode setting; the final
visual result being a rotating circle of rectangles that grows in radius while the rectangles grow in size - but in a
single script instead of a six-scripts chain.
The improvement in capacity is more than 6 to 1, since now the overal process size to run the script is now well
below 1 GB, while the process size for running the previous version's scripts was a bit lower than 2 GB for each
script in the chain.
The second example script makes the same animation but with clips showing a rotating star, thus producing an
expanding rotating circle of rotating stars.
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadPackage("avslib", "base")
LoadPackage("avslib", "array")
LoadModule("avslib", "filters", "animate")

# Animates expanding rectangles on multiple curves, with varying overlay modes


global _thetas = ArrayRange(0, 2*Pi(), npoints=21)
global _aparam = 40
# r,theta correspond to Archimedes spiral (a*theta, theta)
global _rs = _thetas.ArrayOpValue(_aparam, "*")

Function xpolar(float r, float theta) { return Float(r)*Cos(theta) }


Function ypolar(float r, float theta) { return Float(r)*Sin(theta) }

global xy_path = ArrayPlex( \


ArrayOpArrayFunc(_rs, _thetas, "xpolar").ArrayOpFunc("Round"), \
ArrayOpArrayFunc(_rs, _thetas, "ypolar").ArrayOpFunc("Round") \
)
global wh_dims = ArrayRange(12, 92, 4)
global o_modes = \
"blend,add,blend,subtract,blend,chroma,blend,blend,luma,blend,blend," + \
"lighten,blend,blend,softlight,blend,blend,hardlight,blend,blend"
# one less than xy_path
Function xrot(int x, int y, float angle) {
return Round(x*Cos(angle) - y*Sin(angle))
}
Function yrot(int x, int y, float angle) {
return Round(x*Sin(angle) + y*Cos(angle))
}
# rotates a plexed (x,y) path by angle radians
Function rotate_path(string path, float angle) {
path_x = path.ArrayDeplex(0, 2)
path_y = path.ArrayDeplex(1, 2)
new_x = ArrayOpArrayFunc(path_x, path_y, "xrot", String(angle))
new_y = ArrayOpArrayFunc(path_x, path_y, "yrot", String(angle))
return ArrayPlex(new_x, new_y)
}

# the base effect function


Function rect_effect(clip base, string path, int rect_color) {
rect = BlankClip(base, color=rect_color)
frames = ArrayRange(0, base.Framecount - 1, npoints=21).ArrayOpFunc("Round")
# relocate path to center of base clip
xp = path.ArrayDeplex(0,2).ArrayOpValue(Round(base.Width / 2), "+")
yp = path.ArrayDeplex(1,2).ArrayOpValue(Round(base.Height / 2), "+")
# not specifying a mask == full white mask
return PolygonAnim(base, rect, frames, xp, yp, 1.0, wh_dims, \
wh_dims, mode=o_modes)
}
# the angle step to rotate base (x,y) path ( 2pi/{number of curves} ) the
# last being 12
global theta = Pi()/6 # 30 degrees

# since color constants are globals creating an array with their names will
# return their value
global in_colors =
"color_gold,color_ivory,color_mediumorchid,color_beige,color_aquamarine,” +\
"color_blue,color_darkorange,color_white,color_darkred," + \
"color_crimson,color_olivedrab,color_chocolate"
Function MakeEffect006(clip base) {
c = base
c = c.rect_effect(xy_path, in_colors.ArrayGet( 0))
c = c.rect_effect(xy_path.rotate_path( theta), in_colors.ArrayGet( 1))
c = c.rect_effect(xy_path.rotate_path( 2*theta), in_colors.ArrayGet( 2))
c = c.rect_effect(xy_path.rotate_path( 3*theta), in_colors.ArrayGet( 3))
c = c.rect_effect(xy_path.rotate_path( 4*theta), in_colors.ArrayGet( 4))
c = c.rect_effect(xy_path.rotate_path( 5*theta), in_colors.ArrayGet( 5))
c = c.rect_effect(xy_path.rotate_path( 6*theta), in_colors.ArrayGet( 6))
c = c.rect_effect(xy_path.rotate_path( 7*theta), in_colors.ArrayGet( 7))
c = c.rect_effect(xy_path.rotate_path( 8*theta), in_colors.ArrayGet( 8))
c = c.rect_effect(xy_path.rotate_path( 9*theta), in_colors.ArrayGet( 9))
c = c.rect_effect(xy_path.rotate_path(10*theta), in_colors.ArrayGet(10))
c = c.rect_effect(xy_path.rotate_path(11*theta), in_colors.ArrayGet(11))
return c
}

# create a 8sec animation in PAL format


base = BlankClip(color=$020060, length=200, fps=FRATE_PAL, width=WSIZE_PAL,
height=HSIZE_PAL).ConvertToYV12()
return MakeEffect006(base)

Lets now look closer at the first script:


LoadPackage("avslib", "base")
LoadPackage("avslib", "array")
LoadModule("avslib", "filters", "animate")

global _thetas = ArrayRange(0, 2*Pi(), npoints=21)


global _aparam = 40
# r,theta correspond to Archimedes spiral (a*theta, theta)
global _rs = _thetas.ArrayOpValue(_aparam, "*")

Function xpolar(float r, float theta) { return Float(r)*Cos(theta) }


Function ypolar(float r, float theta) { return Float(r)*Sin(theta) }

global xy_path = ArrayPlex( \


ArrayOpArrayFunc(_rs, _thetas, "xpolar").ArrayOpFunc("Round"), \
ArrayOpArrayFunc(_rs, _thetas, "ypolar").ArrayOpFunc("Round") \
)
global wh_dims = ArrayRange(12, 92, 4)
global o_modes = \
"blend,add,blend,subtract,blend,chroma,blend,blend," + \
"luma,blend,blend,lighten,blend,blend,softlight,blend," + \
"blend,hardlight,blend,blend" # one less than xy_path

Function xrot(int x, int y, float angle) { return Round(x*Cos(angle) - y*Sin(angle)) }


Function yrot(int x, int y, float angle) { return Round(x*Sin(angle) + y*Cos(angle)) }

# rotates a plexed (x,y) path by angle radians


Function rotate_path(string path, float angle) {
path_x = path.ArrayDeplex(0, 2)
path_y = path.ArrayDeplex(1, 2)
new_x = ArrayOpArrayFunc(path_x, path_y, "xrot", String(angle))
new_y = ArrayOpArrayFunc(path_x, path_y, "yrot", String(angle))
return ArrayPlex(new_x, new_y)
}

Up to this point the script loads needed modules and plugins and constructs the spiral path for the movement of
the rectangles. Since the path is defined in polar coordinates, a couple of polar functions are defined to calculate
the x,y cartesian coordinates of the path points.
The x and y arrays of coordinates are then multiplexed, by calling ArrayPlex, in a (x,y) array (the equivalent of a
2D matrix) in order to have one variable to hold all the path info.
Two additional arrays, wh_dims to hold the rectangle size at each path point, and o_modes, to hold the overlay
mode in each path segment between two path points are defined.
Then a function to rotate a (x,y) path by a given angle, rotate_path, is defined. Inside it the path is de-multiplexed
in separate x and y arrays by calling ArrayDeplex; then an appropriate coordinates-rotation function is applied to
them and they are again multiplexed and returned as the new, rotated, path.
# the base effect function
Function rect_effect(clip base, string path, int rect_color) {
rect = BlankClip(base, color=rect_color)
frames = ArrayRange(0, base.Framecount - 1, npoints=21).ArrayOpFunc("Round")
# relocate path to center of base clip
xp = path.ArrayDeplex(0,2).ArrayOpValue(Round(base.Width / 2), "+")
yp = path.ArrayDeplex(1,2).ArrayOpValue(Round(base.Height / 2), "+")
# not specifying a mask == full white mask
return PolygonAnim(base, rect, frames, xp, yp, 1.0, \
wh_dims, wh_dims, mode=o_modes)
}

# the angle step to rotate base (x,y) path ( 2pi/{number of curves} ) the last being
12
global theta = Pi()/6 # 30 degrees

# since color constants are globals creating an array with their names
# will return their value
global in_colors = "color_gold,color_ivory,color_mediumorchid,color_beige," + \
"color_aquamarine,color_blue,color_darkorange,color_white,color_darkred," + \
"color_crimson,color_olivedrab,color_chocolate"
Function MakeEffect006(clip base) {
c = base
c = c.rect_effect(xy_path, in_colors.ArrayGet( 0))
c = c.rect_effect(xy_path.rotate_path( theta), in_colors.ArrayGet( 1))
c = c.rect_effect(xy_path.rotate_path( 2*theta), in_colors.ArrayGet( 2))
c = c.rect_effect(xy_path.rotate_path( 3*theta), in_colors.ArrayGet( 3))
c = c.rect_effect(xy_path.rotate_path( 4*theta), in_colors.ArrayGet( 4))
c = c.rect_effect(xy_path.rotate_path( 5*theta), in_colors.ArrayGet( 5))
c = c.rect_effect(xy_path.rotate_path( 6*theta), in_colors.ArrayGet( 6))
c = c.rect_effect(xy_path.rotate_path( 7*theta), in_colors.ArrayGet( 7))
c = c.rect_effect(xy_path.rotate_path( 8*theta), in_colors.ArrayGet( 8))
c = c.rect_effect(xy_path.rotate_path( 9*theta), in_colors.ArrayGet( 9))
c = c.rect_effect(xy_path.rotate_path(10*theta), in_colors.ArrayGet(10))
c = c.rect_effect(xy_path.rotate_path(11*theta), in_colors.ArrayGet(11))
return c
}
The base effect function, rect_effect, demultiplexes the supplied path, translates, using ArrayOpValue, all
coordinates so that they correspond to the center of the overlay clip and passes the arrays to PolygonAnim filter to
draw the animation accross the supplied path. Frame numbers are calculated dynamically, based on base clip's
length, with the aid of ArrayRange function.
A small note here: the excersized reader may have already noticed that if separate x and y arrays where used
instead of a combined (x,y) array we would avoid the costs of uneeded multiplexing and demultiplexing
operations with only the small added complexity of passing one more parameter; however this is a demonstration
script, thus we can afford to be a bit more un-optimized in order to show in addition the way to construct a
combined (x,y) path for the case someone needs it at the future!
The rest is the definition of rotation angle, of rectangles' colors and of the overall effect function, which simply
calls the base effect function for all elements of the colors array with increasing rotation angle.
# create a 8sec animation in PAL format
base = BlankClip(color=$020060, length=200, fps=FRATE_PAL, width=WSIZE_PAL, \
height=HSIZE_PAL).ConvertToYV12()
return MakeEffect006(base)

Finally, a base source is created and the overall animation effect function is called.
The second script example adds a level of complexity and visual appealence to the basic idea, simply because it
can now afford to do so due to the increased capacity of AVSLib version 1.1.0 animation filters: instead of
animating rectangles, it animates clips showing a rotating star. The overal effect is now an expanding rotating
circle of rotating stars.
The second script is as below:
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadPackage("avslib", "base")
LoadPackage("avslib", "array")
LoadModule("avslib", "filters", "resize")
LoadModule("avslib", "filters", "animate")
LoadModule("avslib", "filters", "utility")

# Animates expanding rectangles on multiple curves, with varying overlay modes

global _thetas = ArrayRange(0, 2*Pi(), npoints=21)


global _aparam = 40
# r,theta correspond to Archimedes spiral (a*theta, theta)
global _rs = _thetas.ArrayOpValue(_aparam, "*")

Function xpolar(float r, float theta) { return Float(r)*Cos(theta) }


Function ypolar(float r, float theta) { return Float(r)*Sin(theta) }

global xy_path = ArrayPlex( \


ArrayOpArrayFunc(_rs, _thetas, "xpolar").ArrayOpFunc("Round"), \
ArrayOpArrayFunc(_rs, _thetas, "ypolar").ArrayOpFunc("Round") \
)
global wh_dims = ArrayRange(12, 92, 4)
global o_modes = \
"blend,add,blend,subtract,blend,chroma,blend,blend,luma,blend,blend," + \
"lighten,blend,blend,softlight,blend,blend,hardlight,blend,blend"
# one less than xy_path

Function xrot(int x, int y, float angle) { return Round(x*Cos(angle) - y*Sin(angle)) }


Function yrot(int x, int y, float angle) { return Round(x*Sin(angle) + y*Cos(angle)) }

# rotates a plexed (x,y) path by angle radians


Function rotate_path(string path, float angle) {
path_x = path.ArrayDeplex(0, 2)
path_y = path.ArrayDeplex(1, 2)
new_x = ArrayOpArrayFunc(path_x, path_y, "xrot", String(angle))
new_y = ArrayOpArrayFunc(path_x, path_y, "yrot", String(angle))
return ArrayPlex(new_x, new_y)
}

# the base effect function


Function rect_effect(clip base, clip effmask, string path, int rect_color) {
rect = BlankClip(base, color=rect_color)
frames = ArrayRange(0, base.Framecount - 1, npoints=21).ArrayOpFunc("Round")
# relocate path to center of base clip
xp = path.ArrayDeplex(0,2).ArrayOpValue(Round(base.Width / 2), "+")
yp = path.ArrayDeplex(1,2).ArrayOpValue(Round(base.Height / 2), "+")
return PolygonAnim(base, rect, frames, xp, yp, 1.0, wh_dims, wh_dims,
mode=o_modes, mask=effmask)
}

# the angle step to rotate base (x,y) path ( 2pi/{number of curves} ) the last
# being 12
global theta = Pi()/6 # 30 degrees

# since color constants are globals creating an array with their names will
# return their value
global in_colors =
"color_gold,color_ivory,color_mediumorchid,color_beige,color_aquamarine, + \
"color_blue,color_darkorange,color_white,color_darkred," + \
"color_crimson,color_olivedrab,color_chocolate"
Function MakeEffect006(clip base, clip effmask) {
c = base
c = c.rect_effect(effmask, xy_path, in_colors.ArrayGet( 0))
c = c.rect_effect(effmask, xy_path.rotate_path( theta), in_colors.ArrayGet( 1))
c = c.rect_effect(effmask, xy_path.rotate_path( 2*theta), in_colors.ArrayGet( 2))
c = c.rect_effect(effmask, xy_path.rotate_path( 3*theta), in_colors.ArrayGet( 3))
c = c.rect_effect(effmask, xy_path.rotate_path( 4*theta), in_colors.ArrayGet( 4))
c = c.rect_effect(effmask, xy_path.rotate_path( 5*theta), in_colors.ArrayGet( 5))
c = c.rect_effect(effmask, xy_path.rotate_path( 6*theta), in_colors.ArrayGet( 6))
c = c.rect_effect(effmask, xy_path.rotate_path( 7*theta), in_colors.ArrayGet( 7))
c = c.rect_effect(effmask, xy_path.rotate_path( 8*theta), in_colors.ArrayGet( 8))
c = c.rect_effect(effmask, xy_path.rotate_path( 9*theta), in_colors.ArrayGet( 9))
c = c.rect_effect(effmask, xy_path.rotate_path(10*theta), in_colors.ArrayGet(10))
c = c.rect_effect(effmask, xy_path.rotate_path(11*theta), in_colors.ArrayGet(11))
return c
}

# create a 8sec animation in PAL format


base = BlankClip(color=$020060, length=200, fps=FRATE_PAL, width=WSIZE_PAL,
height=HSIZE_PAL)
base = base.ConvertToYV12()
effmask = ImageSource("star%06d.jpg", 0, 48, 25.0).Reverse().Loop(10).Trim(0,199)
effmask = effmask.ResizeToTarget(base).ConvertToTarget(base).ScaleToPC()
return MakeEffect006(base, effmask)

The base effect function now accepts one more argument, a clip mask, which is passed to the PolygonAnim filter.
The same is true for the overall effect function, since it must pass the mask to the base effect function.
In addition, two more modules are loaded, to provide the filters (ResizeToTarget and ConvertToTarget) that
convert the mask's source image sequence into a clip with the same characteristics as the base clip.
The top-level section of the script loads the image sequence and (with the filters above) converts it to a mask clip
compatible with the base clip. ScaleToPC ensures that the mask is in full [0..255] range.

The result of running the script is presented below.


15. Per frame filtering, a position + size + color animation
This series of example scripts demonstrates the capabilities offered by the filters of the new in AVSLib version
1.1.0 filters :: frames module. The filter used in the examples is FrameFilterReader.
The first example script moves a rotating star accross a complex closed x,y curve, while in parallel its dimensions
(width and height) oscillate giving the impression of the star tilting accross the horizontal and vertical axes. At the
same time the star's color varies constantly due to variation of its RGB components.
The first script:
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "base", "constants")


LoadPackage("avslib", "array")
LoadModule("avslib", "clip", "core")
LoadModule("avslib", "filters", "frames")
LoadModule("avslib", "filters", "resize")
LoadModule("avslib", "filters", "utility")

# afford a start/end blank to make code nicer to look


# it will be cleaned by the stuff below
varfiles = """
r.txt
g.txt
b.txt
w.txt
h.txt
x.txt
y.txt
"""
old = ArrayDelimiterSet(CRLF)
okflag = varfiles.ArrayOpFunc("Exist").ArrayOpFunc("CInt")
varfiles = varfiles.ArrayReduce(okflag)
old = ArrayDelimiterSet(old)

FilterScript = """
star_mask=%g
rect_color = MakeRGBColor(${read1}, ${read2}, ${read3})
ovl = BlankClip(last, width=last.SafeWidth(${read4}), \
height=last.SafeHeight(${read5}), color=rect_color)
star_mask = star_mask.Resize(ovl.Width, ovl.Height).ScaleToPC()
Overlay(last, ovl, ${read6} - Round(ovl.Width / 2), \
${read7} - Round(ovl.Height / 2), mask=star_mask)
"""

clp = BlankClip(color=$102005, pixel_type="yv12", length=300)

effmask = ImageSource("star%06d.jpg", 0, 48, 25.0).Reverse().Loop(10).Trim(0,299)


effmask = effmask.ResizeToTarget(clp).ConvertToTarget(clp).ScaleToPC()

SetDefaultResizer("bicubic")
FrameFilterReader(clp, FilterScript, varfiles, effmask)

Lets now look closer at the first script:


LoadModule("avslib", "base", "constants")
LoadPackage("avslib", "array")
LoadModule("avslib", "clip", "core")
LoadModule("avslib", "filters", "frames")
LoadModule("avslib", "filters", "resize")
LoadModule("avslib", "filters", "utility")

# afford a start/end blank to make code nicer to look


# it will be cleaned by the stuff below
varfiles = """
r.txt
g.txt
b.txt
w.txt
h.txt
x.txt
y.txt
"""
old = ArrayDelimiterSet(CRLF)
okflag = varfiles.ArrayOpFunc("Exist").ArrayOpFunc("CInt")
varfiles = varfiles.ArrayReduce(okflag)
old = ArrayDelimiterSet(old)

After loading the necessary modules, a CR/LF delimited array of seven text files is declared. They will be read by
FrameFilterReader and set the values of seven unique to each filter call global variables that will automatically be
created by FrameFilterReader. The format of the files is that of the ConditionalReader standard Avisynth filter.
The lines immediately after clean-up the array from non-existent entries; their purpose here is to allow line breaks
to occur inside the filenames' array (useful for visually grouping files and formatting).
FilterScript = """
star_mask=%g
rect_color = MakeRGBColor(${read1}, ${read2}, ${read3})
ovl = BlankClip(last, width=last.SafeWidth(${read4}), \
height=last.SafeHeight(${read5}), color=rect_color)
star_mask = star_mask.Resize(ovl.Width, ovl.Height).ScaleToPC()
Overlay(last, ovl, ${read6} - Round(ovl.Width / 2), \
${read7} - Round(ovl.Height / 2), mask=star_mask)
"""

clp = BlankClip(color=$102005, pixel_type="yv12", length=300)

effmask = ImageSource("star%06d.jpg", 0, 48, 25.0).Reverse().Loop(10).Trim(0,299)


effmask = effmask.ResizeToTarget(clp).ConvertToTarget(clp).ScaleToPC()

Next, the prototype script that will be executed in every frame is assigned to the FilterScript string variable, the
base clip of the animation (clp) is created and the rotating star image sequence is loaded and converted to a clip
(effmask) with the same colospace and dimensions as the base clip.
The prototype script assings a mask (to be supplied as argument) to the star_mask local variable and an rgb color
to rect_color. The later is created by the first three global variables that will be read by FrameFilterReader from
the r.txt, g.txt and b.txt text files, respectively. To combine the three integer values (in the range [0..255] the
function MakeRGBColor is used.
Then a rect_color-colored clip with dimensions set by the global variables that are read from the w.txt and h.txt
text files is created. SafeWidth and SafeHeight ensure that the dimensions will be compatible with base clip's
colorspace, thus preventing an error message showing when the script will be passed internally by
FrameFilterReader to ScriptClip.
Afterwards, star_mask is resized to the same dimensions as ovl using the Resize filter. The later was selected
because it does not hard-code a specific resizer selection inside the script (see below) thus making the script more
reusable; for example appropriate for deriving a function that is based on it.
Finally, the colored clip is overlayed on top of the base clip using star_mask as the overlay mask, with its center in
in x,y coordinates read by FrameFilterReader from files x.txt and y.txt.
SetDefaultResizer("bicubic")
FrameFilterReader(clp, FilterScript, varfiles, effmask)

The rest of the script selects a specific resizer to be used by the Resize filter (with SetDefaultResizer) and calls
FrameFilterReader to do the per frame animation.
The second script is:
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "base", "constants")


LoadPackage("avslib", "array")
LoadPackage("avslib", "string")
LoadModule("avslib", "clip", "core")
LoadModule("avslib", "filters", "frames")
LoadModule("avslib", "filters", "resize")
LoadModule("avslib", "filters", "utility")
# afford a start/end blank to make code nicer to look
# it will be cleaned by the stuff below
varfiles = """
r.txt
g.txt
b.txt
w.txt
h.txt
x.txt
y.txt
"""
old = ArrayDelimiterSet(CRLF)
okflag = varfiles.ArrayOpFunc("Exist").ArrayOpFunc("CInt")
varfiles = varfiles.ArrayReduce(okflag)
old = ArrayDelimiterSet(old)

FilterScript = """
star_mask=%g
x_ofs = %i
y_ofs = %i
rect_color = %b ? color_white : MakeRGBColor(${read1}, ${read2}, ${read3})
ovl = BlankClip(last, width=last.SafeWidth(${read4}), \
height=last.SafeHeight(${read5}), color=rect_color)
star_mask = star_mask.Resize(ovl.Width, ovl.Height).ScaleToPC()
Overlay(last, ovl, x_ofs + ${read6} - Round(ovl.Width / 2), \
y_ofs + ${read7} - Round(ovl.Height / 2), mask=star_mask)
"""

clp = BlankClip(color=$102005, pixel_type="yv12", length=300)

effmask = ImageSource("star%06d.jpg", 0, 48, 25.0).Reverse().Loop(10).Trim(0,299)


effmask = effmask.ResizeToTarget(clp).ConvertToTarget(clp).ScaleToPC()

SetDefaultResizer("bicubic")

Function MakeEffect(int xofs, int yofs, clip base, \


string script, string files, clip effmask, bool is_mask)
{
return FrameFilterReader(base.BlankClip(), script, files, effmask, xofs, \
yofs, is_mask)
}

xofs = "0,60,-60,0,0,43,43,-43,-43"
yofs = "0,0,0,60,-60,43,-43,43,-43"
clips = ArrayOpArrayFunc(xofs, yofs, "MakeEffect", \
StrPrint("%g, %q, %q, %g, %b", clp, FilterScript, varfiles, effmask, false))
masks = ArrayOpArrayFunc(xofs, yofs, "MakeEffect", \
StrPrint("%g, %q, %q, %g, %b", clp, FilterScript, varfiles, effmask, true))

global ret = clp

Function OverlayEffect(clip clp, clip clpmask)


{
global ret = Overlay(ret, clp, mask=clpmask.ScaleToPC())
return true
}

dummy = ArrayOpArrayFunc(clips, masks, "OverlayEffect")


return ret

The second script example demonstrates the ability to call the filters of the frames module multiple times in our
scripts, without the need to manage globals; they are all taken care by them.
The example executes the same animation in a group of clips, with constant x,y offsets from the central
coordinates defined inside the x.txt and y.txt files. Thus instead of a single moving rotating star the script now
moves a circle of rotating stars.
The differences with the previous script are presented:
...
LoadPackage("avslib", "string")
...
FilterScript = """
star_mask=%g
x_ofs = %i
y_ofs = %i
rect_color = %b ? color_white : MakeRGBColor(${read1}, ${read2}, ${read3})
ovl = BlankClip(last, width=last.SafeWidth(${read4}), \
height=last.SafeHeight(${read5}), color=rect_color)
star_mask = star_mask.Resize(ovl.Width, ovl.Height).ScaleToPC()
Overlay(last, ovl, x_ofs + ${read6} - Round(ovl.Width / 2), \
y_ofs + ${read7} - Round(ovl.Height / 2), mask=star_mask)
"""
...

The per frame script now contains two more lines to get the x, y offset arguments, a conditional statement to
return a white clip if an (argument) boolean flag is set, in order for the clip to be used as mask and a change in
Overlay arguments in oder for the x, y offsets to have effect.
...
Function MakeEffect(int xofs, int yofs, clip base, \
string script, string files, clip effmask, bool is_mask)
{
return FrameFilterReader(base.BlankClip(), script, files, effmask, xofs, yofs,
is_mask)
}
xofs = "0,60,-60,0,0,43,43,-43,-43"
yofs = "0,0,0,60,-60,43,-43,43,-43"
clips = ArrayOpArrayFunc(xofs, yofs, "MakeEffect", \
StrPrint("%g, %q, %q, %g, %b", clp, FilterScript, varfiles, effmask, false))
masks = ArrayOpArrayFunc(xofs, yofs, "MakeEffect", \
StrPrint("%g, %q, %q, %g, %b", clp, FilterScript, varfiles, effmask, true))

global ret = clp

Function OverlayEffect(clip clp, clip clpmask)


{
global ret = Overlay(ret, clp, mask=clpmask.ScaleToPC())
return true
}

dummy = ArrayOpArrayFunc(clips, masks, "OverlayEffect")


return ret

The body of the script now contains a function to create the moving star effect (MakeEffect) and two arrays to
hold the x, y offsets for each rotating star clip.
The clips are created by operating, with ArrayOpArrayFunc, MakeEffect on both x, y offset arrays. StrPrint is used
to construct the argument lists of the additional arguments to pass to MakeEffect by the array operator.
The overall effect is created using a global clip as accumulator, to accept all the overlays performed, and a second
function (OverlayEffect) to perform each overlay. The function is applied to all elements of the clip and mask
arrays again with a call to ArrayOpArrayFunc. After that the global overaly accumulator is return as the script's
return value.
16. Per frame filtering, exporting specific frame(s)
This series of example scripts demonstrates the capabilities offered by the filters of the new in AVSLib version
1.1.0 filters :: frames module. In particular, they serve as an example of how one can easily create new custom
filters from them.
All example scripts export specific frames as images (using internally the ImageWriter standard Avisynth filter),
but in a different flavor. All have the frame export facilities wrapped inside a custom function, so that they can
easily be reused in your scripts . The first script is:
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "array", "properties")


LoadModule("avslib", "filters", "frames")
Function ExportFrames(clip clp, string frames, string "path", string "type", \
bool "info")
{
# frames export runtime script; needs array::properties module
FF_EXPORT = """
expframes = %q
file = %q
type = LCase(%q)
info = %b
# Overlay is used to avoid colorspace conversion if type != ebmp
expframes.ArrayContains(current_frame) ? ( \
type == "ebmp" ? \
ImageWriter(last, file, current_frame, current_frame + 1, type, info) \
: \
Overlay(last, ImageWriter(last.ConvertToRGB24, file, current_frame, \
current_frame + 1, type, info), opacity=0, ignore_conditional=true) \
) : last
"""
path = Default(path, "frame")
type = Default(type, "ebmp")
info = Default(info, false)
return FrameFilter(clp, FF_EXPORT, frames, path, type, info)
}
expframes = "5,23,35,55,99" # export these frames only
clp = AVISource("story.avi").ConvertToYUY2
ExportFrames(clp, expframes, "selected", "jpg")
Compare(last, clp) # verify that clp is passed through ExportFrames untouched
Lets now look closer at the first script. This defines a new filter, ExportFrames, that exports any frame(s) whose
framenumber(s) is(are) contained in an array passed as argument.
LoadModule("avslib", "array", "properties")
LoadModule("avslib", "filters", "frames")

Function ExportFrames(clip clp, string frames, string "path", string "type", \


bool "info")
{
# frames export runtime script; needs array::properties module
FF_EXPORT = """
expframes = %q
file = %q
type = LCase(%q)
info = %b
# Overlay is used to avoid colorspace conversion if type != ebmp
expframes.ArrayContains(current_frame) ? ( \
type == "ebmp" ? \
ImageWriter(last, file, current_frame, current_frame + 1, type, info) \
: \
Overlay(last, ImageWriter(last.ConvertToRGB24, file, current_frame, \
current_frame + 1, type, info), opacity=0, ignore_conditional=true) \
) : last
"""
path = Default(path, "frame")
type = Default(type, "ebmp")
info = Default(info, false)
return FrameFilter(clp, FF_EXPORT, frames, path, type, info)
}

The larger part of the filter is the runtime script that does the frame exporting. The script arguments are first
assigned to local variables. This makes the script easier to read and saves the need to supply the same argument
many times if it is used in more than one location in the script.
Then a simple test with the runtime variable current_frame is performed: if it is in the array with frame numbers
passed in (the expframes local variable) then the frame is exported; else not. Using the AVSLib-supplied
ArrayContains function makes this test a simple one-liner.
One of the design targets of the filter is to let the clip passed in to go through untouched, whatever is the export
image type requested. This is of concern for types other than "ebmp", since then the ImageWriter standard
Avisynth filter requires that the input is RGB24 and a colorspace conversion would then be required (because in
order to export a frame the filter must be in the active filter chain, thus it must deliver the converted to RGB24
frame to its successor filter, for it to convert it back to the original colorspace).
Thus, the script forks on export image type with a conditional operator and if type != "ebmp" it combines
ImageWriter with Overlay with an opacity of zero to achieve letting the source clip untouched.
The rest of the filter's code initialises the filter's optional arguments to default values (see the ImageWriter's
documentation for details) and calls FrameFilter to do the actual processing.
expframes = "5,23,35,55,99" # export these frames only
clp = AVISource("story.avi").ConvertToYUY2
ExportFrames(clp, expframes, "selected", "jpg")
Compare(last, clp) # verify that clp is passed through ExportFrames untouched
The main body of the script tests the filter's implementation with a real source clip (substitute your own to verify)
and a random selection of frames (expframes variable). The source clip, which in our test case was YV12, is
converted to a colorspace supported by Compare which is used to verify that the input and the return value of the
ExportFrames filter are identical.
Second script is:
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "array", "properties")


LoadModule("avslib", "filters", "frames")

Function ExportFramesEvery(clip clp, int step_size, string offsets, \


string "path", string "type", bool "info")
{
Assert(step_size > 0, "ExportFramesEvery: 'step_size' must be positive")
# frames export runtime script; needs array::properties module
FF_EXPORT_EVERY = """
step = %i
offsets = %q
file = %q
type = LCase(%q)
info = %b
# Overlay is used to avoid colorspace conversion if type != ebmp
offsets.ArrayContains(current_frame % step) ? ( \
type == "ebmp" ? \
ImageWriter(last, file, current_frame, current_frame + 1, type, info) \
: \
Overlay(last, ImageWriter(last.ConvertToRGB24, file, current_frame, \
current_frame + 1, type, info), opacity=0, ignore_conditional=true) \
) : last
"""
path = Default(path, "frame")
type = Default(type, "ebmp")
info = Default(info, false)
return FrameFilter(clp, FF_EXPORT_EVERY, step_size, offsets, path, type, info)
}
clp = AVISource("story.avi").ConvertToYUY2
ExportFramesEvery(clp, 12, "0,3,5,11", "sel_every_", "png")
Compare(last, clp) # verify that clp is passed through ExportFramesEvery untouched
The second script defines a new filter, ExportFramesEvery, that works in a similar way with the SelectEvery
standard Avisynth filter but instead delivering a new clip with the selected frames it exports them as images and
returns the input clip untouched.
Another difference with SelectEvery is that here offsets are contained in an AVSLib array; however if the default
array delimiter is used when the filter is called, the array is simply the argument list that would be passed to
SelectEvery after the "step_size" argument enclosed in double quotation marks.
The decision to use an array was to make easier supplying the rest arguments (from ImageWriter) that the filter
supports. As a by-product this also raises the 60 arguments-limit of Avisynth; you can pass as many numbers
inside the array as wished.
LoadModule("avslib", "array", "properties")
LoadModule("avslib", "filters", "frames")
Function ExportFramesEvery(clip clp, int step_size, string offsets, string "path", \
string "type", bool "info")
{
Assert(step_size > 0, "ExportFramesEvery: 'step_size' must be positive")
# frames export runtime script; needs array::properties module
FF_EXPORT_EVERY = """
step = %i
offsets = %q
file = %q
type = LCase(%q)
info = %b
# Overlay is used to avoid colorspace conversion if type != ebmp
offsets.ArrayContains(current_frame % step) ? ( \
type == "ebmp" ? \
ImageWriter(last, file, current_frame, current_frame + 1, type, info) \
: \
Overlay(last, ImageWriter(last.ConvertToRGB24, file, current_frame, \
current_frame + 1, type, info), opacity=0, ignore_conditional=true) \
) : last
"""
path = Default(path, "frame")
type = Default(type, "ebmp")
info = Default(info, false)
return FrameFilter(clp, FF_EXPORT_EVERY, step_size, offsets, path, type, info)
}

The differences with the previous filter are suprisingly little:


1. An additional argument of the runtime script (step_size) is assigned to a local variable (step); the
argument list of the call to FrameFilter is changed accordingly.
2. The containment test (now on the offsets array) is done to the modulo of division of current_frame
runtime variable with step (again with ArrayContains).
Here also the design target of the filter is to let the clip passed in to go through untouched, whatever is the export
image type requested. Thus, the script forks on export image type with a conditional operator just like the previous
example.
clp = AVISource("story.avi").ConvertToYUY2
ExportFramesEvery(clp, 12, "0,3,5,11", "sel_every_", "png")
Compare(last, clp) # verify that clp is passed through ExportFramesEvery untouched

The main body of the script tests the filter's implementation with a real source clip (substitute your own to verify)
and a random selection of frames, coded directly inside the filter call. The source clip, which in our test case was
YV12, is converted to a colorspace supported by Compare, which is used to verify that the input and the return
value of the ExportFramesEvery filter are identical.
The third script is
# AVSLib :: sample script
# Copyright (c) 2007 George Zarkadas (gzarkadas@users.sourceforge.net)
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version. This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details. You should have received a copy of the GNU General Public License along
# with this program; if not, write to the "Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "filters", "frames")

Function ExportFramesReader(clip clp, string framesfile, string "path", \


string "type", bool "info")
{
# frames export runtime script
FF_EXPORT_READER = """
file = %q
type = LCase(%q)
info = %b
# Overlay is used to avoid colorspace conversion if type != ebmp
${read1} != 0 ? ( \
type == "ebmp" ? \
ImageWriter(last, file, current_frame, current_frame + 1, type, info) \
: \
Overlay(last, ImageWriter(last.ConvertToRGB24, file, current_frame, \
current_frame + 1, type, info), opacity=0, ignore_conditional=true) \
) : last
"""
path = Default(path, "frame")
type = Default(type, "ebmp")
info = Default(info, false)
return FrameFilterReader(clp, FF_EXPORT_READER, framesfile, path, type, info)
}
clp = AVISource("story.avi").ConvertToYUY2
ExportFramesReader(clp, "frames.txt", "reader", "jpeg")
Compare(last, clp) # verify that clp is passed through ExportFramesReader untouched

The third script defines a new filter, ExportFramesReader, that gets the framenumbers to export from a text file
such as those read by the ConditionalReader standard Avisynth filter. The text file, a sample of which is provided
must contain int values different from zero for every frame that is to be exported.
The text file, a sample of which is provided here, must contain int values different from zero for every frame that
is to be exported.
type int
default 0
5 1
12 1
23 1
99 1
100 1
101 1
155 1
212 1
222 1
345 1
512 1
513 1
514 1
515 1

LoadModule("avslib", "filters", "frames")


Function ExportFramesReader(clip clp, string framesfile, string "path", \
string "type", bool "info")
{
# frames export runtime script
FF_EXPORT_READER = """
file = %q
type = LCase(%q)
info = %b
# Overlay is used to avoid colorspace conversion if type != ebmp
${read1} != 0 ? ( \
type == "ebmp" ? \
ImageWriter(last, file, current_frame, current_frame + 1, type, info) \
: \
Overlay(last, ImageWriter(last.ConvertToRGB24, file, current_frame, \
current_frame + 1, type, info), opacity=0, ignore_conditional=true) \
) : last
"""
path = Default(path, "frame")
type = Default(type, "ebmp")
info = Default(info, false)
return FrameFilterReader(clp, FF_EXPORT_READER, framesfile, path, type, info)
}

Again, the differences with the previous filters are very little, essentially the test condition. Here there is no need
for containment test; the special ${read1} variable (it will be substituted by FrameFilterReader by the actual
variable that is set on each frame by the contents of the text file) is directly compared to zero and if not equal the
frame is exported.
Here also the design target of the filter is to let the clip passed in to go through untouched, whatever is the export
image type requested. Thus, the script forks on export image type with a conditional operator just like the previous
examples.
clp = AVISource("story.avi").ConvertToYUY2
ExportFramesReader(clp, "frames.txt", "reader", "jpeg")
Compare(last, clp) # verify that clp is passed through ExportFramesReader untouched

The main body of the script tests the filter's implementation with a real source clip (substitute your own to verify)
and a random selection of frames, coded inside the text file. The source clip, which in our test case was YV12, is
converted to a colorspace supported by Compare, which is used to verify that the input and the return value of the
ExportFramesReader filter are identical.
Tutorials

Understanding containers
Container types are implemented as specially delimited strings. Elements are accessed (retrieved,set) with the use
of functions, where an integer index argument specifies the desired element to operate with. This is the only way
to implement them with the capabilities offered by the Avisynth script language while retaining relative simplicity
and atomicity of container types' variables.

Implementation selections
The valid index range was selected to be from zero to number-of-elements minus one, both because it is the more
usual case and because it makes coding easier. Furthermore, it was decided to allow negative indices, in the style
used by the Python programming language.
Thus, the access functions add number-of-elements to negative indices and then check if resulting index is in the
interval [0..number-of-elements); if yes the element is accessed, else an 'index error' occures. This makes easier to
access container elements backwards from the end (for example, to access the last element, use an index of -1).
The index is checked during each element or subrange access for containment in the interval [0..number-of-
elements); this assures that an out of bound index (a common programming error) will be reported to the user.
In order to implement clip containers a scheme was deviced for copying clips passed to containers in "reserved"
global variables and storing these global variables' names into the container.
Rather than having a special type of clip container it was chosen to create a unified implementation of container
types which can handle every possible type. For this purpose special handler functions were created to
transparently set/retrieve variables of the appropriate type to/from the string representation of them in the
container. The actions of the handler depend on the type of operation:
Operation Handler's actions
Evaluate the element as an expression (by passing it to the Eval() standard Avisynth
function).
Retrieve an element
If the element evaluates, return the result of the evaluation.
Else, return the element itself (ie the string stored in element).
If the new value is of the clip type, copy it to a newly created "reserved" global
Assign to an element variable1 and assign the name of the global variable to the element.
Else, assing the result of applying String() to new value.
1 The variable is created by combining a prefix with the string representation of an integer counter which is
incremented every time a call to the creation function is made.
The element delimiter was chosen to be variable and not hard-coded, in order to allow the maximum of flexibility
to users. A reasonable default (the comma character) was selected and special globals hold the variables associated
with the delimiters. These were made "private" and accessible by special functions in order to aid error-free
manipulation of them.
For the same reason the element handler functions were also chosen to be variable and accessible by special
functions. However, since this feature is considered to be developer-level, no additional documentation but the
source code will be provided.
Impact of selections on functionality
A first consequence of the above setup is that containers can be created by assigning appropriate string
expressions to variables, such as in the examples below.
# assume library's defaults for delimiters apply
ar1 = "1.2, 3.4, 4.5, 6.7" # whitespace is ignored (allowed)
ar2 = "true, false, true"
ar3 = "This, is, a, nice, day." # whitespace in strings is NOT ignored
# clip arrays can also be directly coded, if elements are globals
global clip1 = AVISource(...)
global clip2 = AVISource(...)
global clip3 = AVISource(...)
global clip4 = AVISource(...)
ar4 = "clip1,clip2,clip3,clip4"

A second one is that accessing containers' elements is slower than directly accessing variables because:
• Any variable retrieved or stored to a container needs to be transformed from string to the desired type
(and vice versa) which results in calling a handler function.
• In order to access an element, a scan of the string for delimiters has to be performed; this is particularly
costly when accessing the last elements of an array or recursing backwards over it, from end to start.
However, keep in mind that the extra time needed when parsing a script to produce frames is compensated more
than enough from the time gained during the development of the script by the flexibility, ease and speed of coding
that containers offer.
Taking into account that this extra time will be in the majority of cases a small fraction of the time needed to
process the video streams, most of the time using containers will be the best choice of implementation.
Another consequence is that container variables can contain apart from the usual case of one type of elements, the
following:
• Elements of different types, in any order and proportion desired.
• Global variables' names or even arbitrary expressions, as long as they contain only globals (variables
and/or functions) and constant values, since Eval() will be called from the handler functions and not from
user code).
In fact one can even store entire scripts in a container (if working only with globals) by embedding blocks of code
in double quotes and assigning them to the container elements [1].
The following examples illustrate the above.
inclip = AVISource(...)
ovclip = AVISource(...)
global rect = BlankClip(width=320, height=240, color=$ffffff)
mixar = "0, 0, true, rect, 0.8"
# mixed arrays can be used as structures
# for reducing arguments, specifying presets, etc.
clipvar = some_user_filter(inclip, ovclip, mixar)
...

branch = ...
# construct an array of size 3 with code blocks
# note the unescaped with backslash lines
codar = \
"global c = BlankClip(color=$ff00cc)
global d = c.Levels(0,1.0,255,0,128)"
\ + "#" + \
"global c = BlankClip(color=$00ff00)
global d = c.ConvertToYUY2().Tweak(hue=135)"
\ + "#" + \
"global c = ColorBars()
global d = c.Levels(0,1.4,255,100,200).ConvertToYUY2().Tweak(hue=150)"
# because code blocks contain commas, # was used as delimiter
# that's why we have to tell AVSLib to use our delimiter
ArrayDelimiterSet("#")
temp = codar.ArrayGet(branch > 2 ? 0 : (branch < 0 ? 1 : 2) )
ArrayDelimiterReset()
# and restore to defaults when finished (see below)
new_clip = some_user_filter(d)
...

Be aware though that this functionality is rarely needed; wrapping code to functions or using the container's
operator functions provided by AVSLib is a more scallable and easier to understand alternative.
Of course, this added flexibility also means that one must be careful with the types stored in the container, since
most of the time uniformity is the desired feature (after all, the major purpose for working with containers is to
perform a series of operations to a group of similar objects).
In particular the following note has to be made:
When creating containers with strings one must be aware that due to the evaluation of each string in a retrieve
action, there is the possibility of retrieving a global's value instead of the string if the contents of the string are the
same with the name of the global.
In addition, the facility provided by Avisynth to allow calling a function without parentheses means that all
function names, both standard and user-defined, obey the same rule. This may lead to strange errors since a
function called without parentheses tries first to operate on the implicit variable last.
For example:
global animals = 34
species = ArrayCreate("fishes", "birds", "animals", "serpents", "humans")
t = species.ArrayGet(2) # t is 34 (an integer) and not "animals"!!
# 'not ' will produce a strange error in ArrayOpValue if the bool package
# is loaded due to the existence of the 'Not' function in the package
# (lang is case insensitive!) and the fact that functions can be called without
parentheses
# (which results in "last" implicit variable supplied as argument).
a9 = "is ,is ,has ,was "
a14 = ArrayOpValue(a9, "not ", "+")
# an error pointing that Avisynth forgotten a previously declared
# local variable appears
In addition, one must be careful if he/she decides to play with the container's delimiters. Since these are global
variables, the effect of setting them to a different value is immediate. The following example demonstrates this
issue:
coords = "100, 10, 200, 25, 300, 40, 400, 80"
# change delimiter to # to allow a string-array with commas inside.
ArrayDelimiterSet("#")
subtitles = "Hey friend, how are you?#Fine, thanks!#Nice weather today."
# This won't work; the entire coords array will be returned.
x0 = coords.ArrayGet(0)
# This won't work either; script execution will halt with an 'index error'.
y0 = coords.ArrayGet(1)
sub1 = subtitles.ArrayGet(0)
sub2 = subtitles.ArrayGet(1)
...

The correct way to code in such situations is to organise access to non-standard arrays in blocks and wrap each
block with calls to the pair of ArrayDelimiterSet() and ArrayDelimiterReset() functions, as demonstrated by the
following example:
coords = "100, 10, 200, 25, 300, 40, 400, 80"
# change delimiter to # to allow a string-array with commas inside.
subtitles = "Hey friend, how are you?#Fine, thanks!#Nice weather today."
x0 = coords.ArrayGet(0)
y0 = coords.ArrayGet(1)
# wrap blocks of operations on non-standard arrays;
# do not access normal arrays inside these blocks.
ArrayDelimiterSet("#")
sub1 = subtitles.ArrayGet(0)
sub2 = subtitles.ArrayGet(1)
ArrayDelimiterReset()
...

What containers can do for you


Well, actually nearly everything, since they are a general purpose programming facility. That's why they are a
standard element of nearly every programming and scripting language.
A few possibilities specific to Avisynth usage are outlined at the list below. Keep in mind though that this is a very
small set; the only limit is imagination.
• Organisation of clips in timelines (ie arrays of clips) and batch application of filters and any type of
processing. For example, in order to combine a collection of titled-at-the-start episodes into a continuous
movie one can use:
• a timeline and an array of titles,
• an animation function inside a custom user function (taking a clip and a string argument) to
create a title-clip with a transition effect and return the combination of the effect and the original
clip,
• the ArrayOpArrayFunc() function on the timeline and titles arrays with the user function
mentioned above,
• the ArraySum() function to join all timeline clips in the final video stream.
• Overlaying of timelines, for example by passing user-function wrappers of Overlay() to
ArrayOpArrayFunc().
• Animation on arbitrary curves, with varying opacity and size. See the animate module's source code for
an example of this use.
• Rotation of clips accross the vertical or horizontal axes, if animated resizing is organised with an
appropriate sequence, an auxiliary video used as a back and FlipVertical() / FlipHorizontal() is applied on
one copy of the clip.
• Operations on clip groups such as stacking in rows, columns or matrices, application of masks, etc.
• Creation of preset collections of clips, masks, curves, etc. as global variables / constants for using with
Import() in scripts.
See the examples at the container operators tutorial and the source code of the test scripts included in the
distribution of AVSLib to get an inshight of real use cases of container types.

Hints for effective use


The following list provides some guidelines for effective use of containers.
• Carefully review the corresponding parts of the library specifications section to avoid exceeding the
allowed limits for containers size (in case you use Avisynth 2.5.5 or earlier).
• Try to use negative indices When accessing elements near the end of the container; they result in easier to
read code.
• Avoid direct manipulation of containers; try to use only the associated AVSLib functions for interacting
with their elements.
• Try to use the associated container operators whenever you want to process a container's elements. This
also applies for subranges, since containers are accompanied with a rich set of functions to operate on
subranges.
• When creating a recursive function that parses a container type try to code it such that it parses the
container forward, from start to end.
• Cache wherever possible the container's number of elements into an integer variable (since determining it
requires parsing the entire string each time it is requested).
• Try to use OOP notation; while it is of course a matter of style, it does makes chaining container related
functions more easier to write (no need to worry if parentheses are coupled) and also promotes the notion
of a container class with properties and methods, which overally enhances code readability.
[1]:Make sure that the code blocks do not generate errors because these will be masked by the try..catch block
of the container's retrieve handler and it will appear that the scheme does not work, while it actually does. A hint
to debugging: If an error appears inside a code block, only the globals assigned before the error occured will have
the correct values. That way you can trace, by examining all associated globals, where the error occured.
Container operators

Introduction
Having a container without a means to conveniently operate on all of its elements is quite disappointing; why then
to have it in the first place? That's why all programming and scripting languages that support containers provide a
means to effectively operate on them.
In most of these languages the means is special looping language constructs (such as the for, while, do..loop, etc.).
In AVSLib, since the underlying script language does not support natively containers at all, it is a set of special
AVSLib functions, collectively called container operators.
Container operators give the ability to operate on all elements of a container in a single step. In addition, coupled
with the subrange selection functions that AVSLib provides for each container type, they give the ability to
operate on subranges of a container in a single step.
Currently AVSLib supports only one container type, the array.

Array operators
There are five fundamental array operator functions, from which a whole family of array operator functions can be
derived. They are presented below:
• ArrayOpValue,
• ArrayOpFunc,
• ArrayOpArray,
• ArrayOpArrayFunc,
• ArraySum,
The first four of the above functions operate on the individual elements of the array (or arrays) passed as
arguments and produce a new array. The fifth operates both on the individual elements of the array and the array
as a whole producing a single value[1], which is the analog of the integral of the array. Let's have a closer look on
them.

ArrayOpValue
The operator function performs the requested operation between a scalar (a single value) and every array element.
In effect the operator performs the [vector] <op> scalar or scalar <op> [vector] action.
The operation, which is provided as a string, can be anyone that Avisynth script language supports for the types of
scalar and element (for example "+", "-", "*", "/", "%", "&&", etc.).
The operator function performs the operation with element as the first operand (ie the expression evaluated is
[element] <op> scalar). If this is not the desired order, the optional argument array_first can be set to false to
reverse the order of the operands (ie to evaluate the expression scalar <op> [element]).
Examples
a1 = ArrayCreate(4, 2, 6, 3, 5, 1, 7)
# lets add 3 to all a1 elements
a2 = ArrayOpValue(a1, 3, "+") # a2 == "7,5,9,6,8,4,10"
# lets divide all a1 elements by 3
a3 = ArrayOpValue(a1, 3, "/") # a3 == "1,0,2,1,1,0,2"
# lets divide 3 by each element of a1 (we need the "false", in order this to work)
a4 = ArrayOpValue(a1, 3, "/", false) # a4 == "0,1,0,1,0,3,0"
# what happened? well all operands are ints and so int division was performed
# now lets force float division by making 3 -> 3.0
a5 = ArrayOpValue(a1, 3.0, "/") # a5 == "1.3333,0.6667,2.0,1.0,1.6667,0.3333,2.3333"
a6 = ArrayOpValue(a1, 3.0, "/", false) # a6 == "0.75,1.5,0.5,1.0,0.6,3.0,0.4286"
______________________________________________________________________________________
# lets create an array of clips and add start_logo and end_logo at their
# beggining and end respectively (single clips are also scalar values)
c1 = AVIsource(...)
...
c10 = AVIsource(...)
start_logo = AVIsource(...)
end_logo = AVIsource(...)
ac1 = ArrayCreate(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10)
# since we are interested in the final result we reassign ac1 to reuse identifiers;
# we also use OOP notation, for its better readability
ac1 = ac1.ArrayOpValue(start_logo, "+", false)
ac1 = ac1.ArrayOpValue(end_logo, "+")
# we are done; note the false in the first call, to put start_logo as the left operand

ArrayOpFunc
The operator function applies a user-defined function to every array element. In effect the operator performs the
f([vector]) action.
The function must accept element as its first argument. Additional arguments can be defined as an argument string
(a string-representation of the additional arguments passed to the function separated by commas).
Examples
# lets calculate the y's of a curve on the interval [40, 200]

# the curve is y = 2.345x-1 + 3.12x - 4.002x1.5


Function my_curve(float x) {
coef = "5.347,-2.11,1.002"
pows = "-1,1,1.2"
return PowSeriesAA(x, coef, pows)
}
cvx = ArrayCreate(40,80,120,160,200,240,280,320,360,400)
cvy = cvx.ArrayOpFunc("my_curve")
# now pass the cvx, cvy to an animation filter such as PolygonAnim()
...
______________________________________________________________________________________
# a custom filter that resizes a clip to NTSC dimensions, adjusts hue,
# brightness and contrast and softens a little between frames
Function my_filter(clip c) {
ret = c.ConvertToYUY2()
ret = ret.BilinearResize(720,480)
ret = ret.Tweak(hue=15, bright=2.5, cont=1.2, coring=false)
ret = ret.TemporalSoften(4,4,8,15,2)
return ret
}
# lets create an array of clips and then apply my_filter() to them
c1 = AVIsource(...)
...
c10 = AVIsource(...)
ac1 = ArrayCreate(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10)
# lets convert all clips' framerate its easier to do in one step
# after array creation; that's operators are made for
ac1 = ac1.ArrayOpFunc("AssumeFPS", "25")
# now apply your custom filter
ac1 = ac1.ArrayOpFunc("my_filter")

ArrayOpArray
The operator function performs the requested operation between every element pair of the two arrays supplied as
arguments. In effect the operator performs the [vector1] <op> [vector2] action.
The operation, which is provided as a string, can be anyone that Avisynth script language supports for the types of
element pairs (for example "+", "-", "*", "/", "%", "&&", etc.).
The order of operands in the expression evaluated ([element] <op> [element]) is decided by the ordering of the
arrays in the argument list; the elements of the first array are always the left operand of the expression.
Examples

# titles and movies are arrays of 20 clips each (say a collection of family clips
# produced during your vacations and the intros for each one, respectively)
titles = ArrayCreate(tvac1, ..., tvac20)
movies = ArrayCreate(mvac1, ..., mvac20)
# convert to common format (if all clips have the same, skip this step)
titles = titles.ArrayOpFunc("ConvertToYUY2")
movies = movies.ArrayOpFunc("ConvertToYUY2")
# now lets combine the intros with the respective family clips
stories = ArrayOpArray(titles, movies, "+")
...
______________________________________________________________________________________
# (x0,y0) and (x0,y4) define two curves on our clip coordinates
x0 = "100,180,260,340,420,500,580"
y0 = "0,100,350,480,350,250,0"
y4 = "50,200,450,580,450,350,50"
# lets generate 3 more curves (x0,y1), (x0,y2), (x0,y3) evenly distributed between
# (x0,y0) and (x0,y4), in order to to feed them all later to an animation function
# such as PolygonAnim()

# 1st step: calculate the span between curves (y4[i] - y0[i])


ysp = ArrayOpArray(y4, y0, "-")
# 2nd step: divide span by 4 and round to integer
ysp = ysp.ArrayOpValue(4.0, "/").ArrayOpFunc("Round")
# 3rd step: get curve n+1 by adding final ysp to curve n
y1 = ArrayOpArray(y0, ysp, "+")
y2 = ArrayOpArray(y1, ysp, "+")
y3 = ArrayOpArray(y2, ysp, "+")

ArrayOpArrayFunc
The operator function applies a user-defined function to every element pair of the two arrays supplied as
arguments. In effect the operator performs the f([vector1],[vector2]) action.
The function must accept element[vector1], element[vector2] as its two first argument. Additional arguments can
be defined as an argument string (a string-representation of the additional arguments passed to the function
separated by commas).
Examples
Function my_subtitle(clip c, string s) {
return c.SubTitle(s, size=24, text_color=$ffffff)
}
c1 = AVIsource(...)
...
c4 = AVIsource(...)
# ac1 is a clip array; at1 is a string array containing subtitles
ac1 = ArrayCreate(c1, c2, c3, c4)
at1 = "subtitle 1,subtitle 2,subtitle 3,subtitle 4"
# create an array with subtitled clips
sc = ArrayOpArrayFunc(ac1, at1, "my_subtitle")
...
______________________________________________________________________________________
# return a simple overlay of the clips passed as arguments
Function my_overlay(clip base, clip ovl, string "omode") {
omode = Default(omode, "blend")
opac = omode == "blend" ? 0.5 : 1.0
return Overlay(base, ovl, mode=omode, opacity=opac)
}
# ac1 and ac2 are two clip arrays with 4 elements each
ac1 = ArrayCreate(c1, c2, c3, c4)
ac2 = ArrayCreate(d1, d2, d3, d4)
# lets overlay them
ov1 = ArrayOpArrayFunc(ac1, ac2, "my_overlay") # this will use 'blend' as mode
# string arguments to user-supplied functions must be quoted
ov2 = ArrayOpArrayFunc(ac1, ac2, "my_overlay", StrQuote("add"))
# lets overlay the results one more time to see what happens
fin = ArrayOpArrayFunc(ov1, ov2, "my_overlay", StrQuote("luma"))
...
ArraySum
The operator function applies an optional elm_func user-defined function to every array element (if none is
supplied it defaults to element itself). It then sums the return values of elm_func with an optional sum_func user-
defined function (if none is supplied it defaults to simple addition: "+"). In effect the operator performs the
sum_func(elm_func([vector])) action which is the equivalent of integrating over the array elements.
Usually, the precise order of application of sum_func will not be of importance. However, if the outcome of
sum_func is not symmetrical to its main operands (ie the first two required arguments which correspond to array
elements), it may be. Therefore, the following paragraph presents the internals of the summing process.
The summing of values is always performed in the backward direction, from array end (element with index
array.ArrayLen()) to start (element with index 0).
Thus, the full expansion of the sum operation has the form (values inside brackets denote array elements with the
designated index, ie [0] means array[0]):
sum_func(elm_func([0], elm_args), sum_func(elm_func([1], elm_args),
sum_func(elm_func([2], elm_args), sum_func( ... sum_func(
elm_func([ArrayLen-2], elm_args), elm_func([ArrayLen-1], elm_args),
sum_args) ... , sum_args), sum_args), sum_args), sum_args)

Therefore, the first argument of sum_func is always the result of the application of elm_func on an array element,
while the second is the result of the succesive application of sum_func on all elm_func results for array elements
with index > element's index. For the last two array elements sum_func is applied directly to the outcomes of
elm_func on them.
Since the order of operation of sum_func is fixed inside the operator function's code, if for any reason a different
order is required, the only way to accomplish this is to use the array manipulation functions (such as
ArrayInvert()) for setting the desired order of array element's before passing it to ArraySum.
Examples
# lets use the array 'ac1' produced by the second example of ArrayOpValue
# 'ac1' contains 10 clips with a front and back-cover logo
# now lets concatenate all stories to a single clip
my_clip = ac1.ArraySum()
______________________________________________________________________________________
# lets use the array 'stories' produced by the first example of ArrayOpArray
# 'stories' contains 20 clips with a front-cover title
# now lets concatenate all stories to a single clip, using Dissolve
# (with overlap=5) to create a smoother transition
my_movie = stories.ArraySum(sum_func="Dissolve", sum_args="5")
______________________________________________________________________________________
# lets calculate an integral and print the results

# the function defining the curve

# y = 2.345x-1 + 3.12x - 4.002x1.5


Function my_f(float x) {
coef = "2.345,3.12,-4.002"
pows = "-1,1,1.5"
return PowSeriesAA(x, coef, pows)
}

# the function calculating the area using trapezoid rule


Function t_area(float y1, float y2, float dx) {
Assert(dx > 0, "dx must be greater than zero")
return (y1 + y2) * dx / 2
}

# divide [0.5..1] to subintervals with width 0.05


ax = ArrayRange(0.5, 1, step=0.05)
# now calculate the integral of a function f(x) ie the area between y=0 and y=f(x)
# use as f(x) 'my_f'
# to calculate the integral use the trapezoid rule (in sum_func)
area = ax.ArraySum(elm_func="my_f", sum_func="t_area", sum_args="0.05")
return Print("The xs are:", ax, "The ys are:", \
ax.ArrayOpFunc("my_f"), "The area is:", area)

Usage (what to do and what not to do)


In order to be able to operate on every container regardless of its elements' type(s) without imposing significant
overhead, operator functions do not check the validity of the parameters passed to them (except some trivial
checks, such as equality of the number of elements of arrays when >1 array are passed as arguments). This has the
consequence that common errors made by the user during the coding of the script, for example
• constructing an array with erroneous values or format (this more easily happens when you hard-code an
array as a string) and then passing it to the operator,
• mispelling a function name,
• forgetting to quote strings (with the StrQuote() function) contained inside the extra argument strings that
a user-supplied function may require,
• forgetting to place commas between the individual arguments composing an extra argument string,
• putting excess commas at the start or end of an extra argument string,
• selecting an operation not supported by the array's elements type (such as "||" for numeric types),
• logic errors inside user-supplied functions that return invalid results,
etc. may result in an error message box by Avisynth pointing inside the code body of the operator function.
There are also many ways (at least for earlier versions of Avisynth) for a call to an operator to crash Avisynth and
the video rendering application, due to the limitations imposed to AVSLib by the host application (Avisynth). Two
classes of possible ways are the following:
• (Avisynth versions 2.5.5 and earlier) If the user instructs the operator function to return a value with a
much larger string representation than the original element (for example an entire array) for each element
of the array parsed and the array is significant in size, a container exceeding the maximum allowed string
limit may be created and a fatal buffer overflow condition will eventually arise.
• If a complex iterrative function for processing container elements is passed to the operator along with a
large container, the Avisynth stack space may well be exausted.
Thus, the following list of best usage procedures should be followed in order to maximize the benefits from
operators and containers altogether.
• Carefully review the library specifications section of the documentation, in order to avoid passing arrays
of inappropriate size to operator functions.
• Before supplying a user function to an operator, test it passing single values as arguments. It is easier to
debug a single function call and you also avoid tampering with the source code of AVSLib.
• Confirm that the arrays passed to the operator have elements with the correct type and value. The
debugging helpers Break and BreakIf are especially useful for this purpose. Simply, break before
invoking the operator function to inspect variables and assure everything looks normal.
• Confirm the validity of all arguments passed to the operator. In particular, ensure that argument strings are
properly constructed.
• Avoid putting break points inside the AVSLib source code; you risk accidentally modifying it. They are
rarely needed also. For example:
• If you want to break inside the ArrayOpValue or ArrayOpArray operator functions, you can use a
custom function to perform the desired operation and then place the breakpoint inside this
function and use ArrayOpFunc or ArrayOpArrayFunc, respectively to achieve the same
operation.
• If you want to break inside the ArrayOpFunc or ArrayOpArrayFunc operator functions, simply
place the breakpoint inside the user function that you supply.
• If you want to break inside ArraySum, provide custom copies of the Self and Sum2 functions
(you can copy the definitions from the base :: core module or provide them by your self; they
simply return x and x1 + x2) for the elm_func and sum_func arguments of ArraySum,
respectively. Then place the breakpoint inside those functions.
If you already supplying a custom function for any of the above arguments, simply place the
breakpoint inside the custom function.
• If you ever need to put a breakpoint inside the AVSLib source code, then make a copy of the original
module(s) file(s) and after debugging replace the modified files with the original copies.
[1]: This
is the usual case. It is though possible, with proper coding of the elm_func and sum_func arguments of
ArraySum function (user-supplied functions) to return an array as a result.
Understanding editing filters

Introduction
Editing filters provide a standardized interface for common editing operations with clips, such as trimming,
replacing parts of a clip with another, inserting and deleting parts and sequentially joining clips.
Currently there are six editing filters, three of which operate on single clips, two on pairs of clips and one on
groups of clips (see the corresponding filter documentation for usage examples):
• EditDelete : Deletes a part of the clip.
• EditInsert : Inserts a part of a clip inside another.
• EditJoin : Joins a group of clips sequentially (one after the other).
• EditReplace : Replaces a part of a clip with a part of another clip
• EditTrim : Returns a portion of a clip, like the Trim standard Avisynth function but with a different set of
parameters.
• EditTrimRange : Returns portions of a clip, typically disjoint, with the same or varying length. The ranges
are joined together in one clip, using EditJoin.
The main advantage of using the editing filters (except of course the standardization and the error checking
performed by them, which are already good reasons to adopt their use) is the ability to specify post-processing
operations on the parts that compose the final result of editing. We will examine this subject in detail at a
following section.

The editing model


All editing filters treat clips as being an array of frames. To promote this notion of an array, frame numbers behave
like array incides. More specifically:
• Valid frame numbers are in the range [0..clip.Framecount)
• When selecting subranges, starting frame number is included in the subrange while ending frame number
is not included.
• Negative frame numbers are supported also, meaning offset from the end of clip (the length of clip ie
clip.Framecount is added to a negative frame number inside the editing functions)[1].
Internally all editing filters use calls to the Trim() standard Avisynth filter to select the requested subranges of
frames and then, as a final step, they assemble the selected subranges and form the final result of the editing
operation.
Depending of the filter called and the values of the parameters, the number of subranges created for each clip or
clip pair may vary from one to three. Because this is of interest to user-supplied functions the following table
presents the possible different cases. For EditTrimRange the discussion for EditJoin applies.
Function Place of operation Parts Comments
At the middle of the clip (frame > 1st and 3rd parts belong to clip #1,
0 and not all frames up to the end 3 2nd part belongs to clip #2 at the
are replaced) function's argument list
At the start of the clip (frame = 0 1st part belongs to clip #2, 2nd part
EditReplace / EditInsert and not all frames up to the end 2 belongs to clip #1 at the function's
are replaced) argument list
At the end of the clip (frame > 0 1st part belongs to clip #1, 2nd part
and all frames up to the end are 2 belongs to clip #2 at the function's
replaced) argument list
At the middle of the clip (frame > Both parts belong to the clip. The
0 and not all frames up to the end 2 start of the original clip belongs to
EditDelete are deleted) the 1st part
At the start or end of the clip 1
At the end of the clip (this is the The 1st part is the entire left clip, the
EditJoin 2
only option) 2nd is the entire right clip1
1 EditJoin may take up to 50 clip arguments but it joins them incrementally and thus in each join only two clips
are participating. The left clip is the combined join of all clips that have been joined so far (ie at the first step it
is the clip #1 at the function's argument clip (the right operand is clip #2), at the second step it is the result of the
combination of clip #1 and clip #2 (the right operand is now clip #3) and so on..

The following figures demonstrate the above.


Figure 1: Clip parts resulting from EditReplace and EditInsert filters' action
Figure 2: Clip parts resulting from EditDelete and EditJoin filters' action

Avisynth provides a number of ways to assemble clips together, namely UnallignedSplice, AllignedSplice and
Dissolve. Instead of having separate versions of each editing filter for each one of these ways, an optional
parameter "op" is declared at the argument list of the filters, the value of which controls the way that final result's
subranges will be assembled together. One more option added by AVSLib is to process the clips by an arbitrary
user-supplied function.
We will examine in more detail this final step of the editing operation at the following section

Assembling the parts of the final result


The editing filters provide four ways to perform the assembly of the parts consisting the final result, controlled by
the value of the op[2] optional parameter:
• By using the UnallignedSplice standard Avisynth filter ie the "+" operator. This is the default operation
when op is ommited.
• By using the AllignedSplice standard Avisynth filter ie the "++" operator.
• By using the Dissolve standard Avisynth filter.
• By using a custom, user supplied function.
For the last two options a second optional parameter, extra_info, is provided in order to supply the necessary
information to the editing function for performing the operation (the overlap in the case of Dissolve and the name
of the user function to call in the last case). In both cases the information must be supplied as a string.
Which selection will be used is application-dependent and we will not analyse this issue in depth.
UnallignedSplice appears to be the most common type of assembling operation and thus it was chosen as the
default, implicit case. Dissolve may be more appropriate when replacing a scene with a similar one from a second
source or when cutting scenes out. See the corresponding filter's documentation for usage examples.
The fourth option (user supplied functions) will be presented in detail since it is a new concept and provides a rich
set of options (transitions, conditional inclusion, amendment of front-cover clips and logos, special effects, etc.)
not found in the other three.
User-supplied functions
User supplied functions provide a generic and versatile mechanism for post-editing clips. We use the term "post-
editing" since the call to the user function is the last step of the editing operation; the final result will be whatever
function(part1, part2, ...) returns.
As a matter of fact, the user function is free to return anything, even a non-clip value (for example an integer).
The only exceptions are EditTrim, where the whole conversation does not apply anyway, and EditJoin when more
than two clips are supplied to it (the user function still can return anything, but it must be a clip).
Of course returning something completely irrelevant to the original clips passed to the editing filter or a non-clip
value is bad, since it breaks the semantics associated with the names of the filters and in general it results in hard
to understand code. Nevertheless, it may be of use in certain situations (for example when you want to insert a clip
only if it meets certain requirements that are associated with the final parts of the editing and not the original clips,
or when an error condition needs to be flagged). Thus, it is left up to the end-user of the library.
Most of the time however, the user function will return something that has direct relation with the supplied clips.
There are many possibilities as pointed out earlier but first let us look at how this user function must be defined.
User supplied functions can expect to be provided with a minimum of one and a maximum of three clips (see the
figures above for a visual presentation). The actual number depends on the type of operation and the frame
number(s) where the operation was requested. The same is true regarding the initial clip from which the part
originates.
Thus, user functions must in general have a parameter list with one required and two optional clips in the first
three argument slots. Additional optional arguments do not harm, but they will never be supplied by the caller
(ie the editing filter). It is however possible to use a function with less clip slots in the argument list if you know
beforehand the number of parts that the editing filter will produce, since the check on arguments' number is done
by Avisynth at runtime.
What the user function does with its parameters (ie the processing of the clip parts) is up to the user, so we will not
go any further. A limited, indicative list of possible applications is presented below:
• Apply a transition effect between the parts.
• Insert a joining clip to provide continuity of the story (such as a "two minutes later..." logo).
• Insert a front-cover clip in front of every clip (most useful when joining clips with EditJoin, say to
construct a movie with a series of episodes.
• Replace a part that does not meet some specifications (for example it is too short) with another or remove
it completely from the final output.
• Insert another clip between the parts, for example a commercial, a diagram (if you are constructing
educational videos), etc.
• Overlay another clip on top of the final result (say a parallel story inside a window, etc.).
• Apply different sets of filters to each part and the overall result.
At the next section a generic example of a user-supplied function is presented to help clarify the above
conversation.

A generic example of a user-supplied function


The following code snippet presents a generic example of a user-supplied function that can be used will all editing
filters and all possible values of their arguments.
Function user_function_template(clip c1, clip "c2", clip "c3") {
# get number of clips supplied and a reasonable default for all arguments
nparts = 1 + (Defined(c2) ? 1 : 0) + (Defined(c3) ? 1 : 0)
c2 = Default(c2, Null(c1))
c3 = Default(c3, Null(c1))
# now perform whatever custom processing the user function is designed for
...
}

The first line stores the number of parts supplied to the user function, while the next ones assure that all arguments
are initialised to clip-type variables. If an argument is not supplied, the Null() function assigns a zero-length clip
to it.
The next lines should perform the intended operations on the clip parts, possibly using the information stored at
the nparts local variable; if you not need it you may remove the corresponding line. A final clip should be returned
at the end.
It should be noted that there is no generic way for the user function to figure out in which of the original clips a
specific part belongs in all cases. While this is an issue only for the cases of EditReplace and EditInsert filters
when only two parts are supplied (see the table at the section "The editing model" above), it is nevertheless
considered a limitation and will be removed in one of the next versions of AVSLib. For the time being, this
knowledge should be derived by the kind of operations that the user performs to the edited clips.
You need not however always use the template above in your scripts, since you know what your script does. This
generic template is actually needed only if you are constructing general-case functions to make a post-editing
library. Most of the time it will be enough to construct simpler variants of the above template such as
• Function user_function_3c(clip c1, clip c2, clip c3) { ... }
• Function user_function_2c(clip c1, clip c2) { ... }
• Function user_function_1c(clip c1) { ... }
Of course you must then assure that the correct variant is used in every case, but this is not difficult.
[1]: See the section Implementation selections at the backgrounder "Understanding containers" for more details.
[2]: The
allowed values for the op parameter are coded into a global set of constants ("EDOP_...") by the filters ::
edit module.
Understanding animation filters

Introduction
Animation filters use a combination of the Overlay and ScriptClip standard Avisynth filters in order to achieve
animation of position (x and y coordinates) and opacity of the overlayed clip (the clip to be animated) on top of
the base clip. Furthermore, they use the Resize filter in order to achieve animation of size (width and height) of
the overlayed clip.
From AVSLib version 1.1.0, animation filters are rewritten internally (use of C++ plugins instead Avisynth scripts
and also change of algorithm, so that ScriptClip instead of Animate is used at the core) in order to improve
memory usage and execution speed. The new version of animation filters is now capable of executing complex
animations in a single script; see the 14th example script for more information.
There is a version for animating between two end points (frame numbers) of a clip, LineAnim(), as well as a
version for animating between an arbitrary number of consecutive points (frames) of a clip, PolygonAnim(). At
each frame number (x,y) position, opacity and size (width,height) can be set independently. The change of them
between animation end-points is linear.
For the PolygonAnim() there is also the ability to specify different parameters regarding the way that the animated
clip is overlayed in each animation segment (such as overlay mode, mask clip, whether the mask is a greyscale
one, etc.).
Thus in principle animation filters can achieve the simulation of any 3D movement of a clip with reference to the
base clip's viewport in which at least one axis remains parallel to one axis of the viewport (that is rotations are
excluded except for the case of rotation along the x or y axes, where it can be simulated with a series of resize-
shift-resize steps and an auxiliary "back" clip) without the need to resort to external plugins.

Animation coordinate system


Animation filters use a coordinate system in which (x,y) coordinates are displaced by half the width and height of
the overlayed clip (ie if w,h are the later, xa = x - w/2, ya = y - h/2). The axes retain the direction of the standard
clip coordinate system (x increases to the right and y to the bottom of the clip).
The selection may seem a bit uncommon at first site, but it was made for a good reason: to allow easy calculation
of the placement of a clip which is animated both in position and size.
Indeed it is a lot easier to define a movement for a clip that constantly changes size in terms of its center; else a
detailed knowledge of its size in each frame is needed to modify the coordinates defining its upper left corner.
Since the size animation functions produce a clip in which the size animated, overlayed clip is assured to be
always centered, it suffices to subtract half the width and height in order to achieve the desired transformation.
To account for this displacement of coordinates inside the animation filters the user must add the same amounts
(w/2 for x and h/2 for y) to every end point passed to them.
For example, if the final size animated clip has (w,h) dimensions equal to (400,200) and we want to position
animate it across a polygon defined by the points
(0,0), (150,50), (300,250), (300,350), (150,370), (-400,300),
with respect to its top-left corner, we must add 200 to each x and 100 to each y value in order to get the polygon
points with respect to its center. The points will then be
(200,100), (350,150), (400,350), (400,450), (350,470), (-200,400).

The significance of masks


All animation filters use masks in order to animate any type of clip on top of any type of clip and allow
consequtive stacking of an arbitrary number of animated clips on a base clip without interference with previous
animations. If no mask is provided, the functions create an all-white mask with the dimensions of the animated
clip.
The masks are animated in parallel with the animated clip. Thus, at each frame the clip affects only the area on top
of which is positioned and all the modes (and other arguments) supported by the Overlay standard Avisynth filter
can be applied without nasty side effects to other areas of the base clip. This mechanism also makes possible to
stack animations on the base clip without cross-interference.
Since the masks are clips and there are argument slots in the animation filters for the user to supply them
explicitly, it is possible to provide masks that they transform during the clip's duration.
This makes possible to animate the shape of the clip also (for example to gradually turn it from rectangular to
elliptical, or to a star-like or an irregular shape, or simulate rotation by creating a rotated white area inside a full-
black mask, etc.). The possibilities are endless.
The only thing that one has to pay attention, if YUV clips are used as masks, is that all masks passed in must be in
the full (PC) range (this is a requirement of Overlay, which is propagated by the animation filters, since they use
Overlay internally).

Usage tips and examples


First of all, except for the simpler cases, create a scenario. Define what effects you want to achieve and the
sequence of events necessary to implement them. Next, identify the components needed for implementing them
(filters, AVSLib functions and data structures, etc.). Then follow the guidelines presented below:
• Organise the animation to small blocks (preferably functions) that can easier be conceived, implemented,
tested and debugged. You can then later chain the blocks to produce the overall animation.
• Proceed step-by-step, verifying the correct operation of each block before going to the next; it is easier to
spot the correct location of errors this way.
• When constructing animation paths always take into account the different coordinate system used by the
animation filters and compensate for that. You may find it easier to work on the usual top-left coordinate
system and then convert values. If you select this way, you will find ArrayOpValue() extremely useful.
• The standard way to animate multiple clips on top of a base clip is to order the first animation on top of
the base clip and then order each subsequent animation on top of the previous result.
For this to work correctly it is essential that masks, if used, are in the full PC range.
Also it is advisable to convert the base clip to a YUV colorspace before applying the animations in order
to avoid excess conversions back and forth between RGB and YUV that are made by the Overlay
standard Avisynth function; else final result's chroma quality will be affected.
Examples of animation filters' uses are provided by some of the example scripts included with AVSLib
documentation.
Using the loader module to build Avisynth script libraries

Introduction
The loader module, new to AVSLib version 1.1.0 provides a set of functions and globals that together form a
unified loading mechanism of Avisynth "modules" (.avsi scripts).
In particular, the loader module allows for loading modules in a minimal fashion, ie only those modules that are
required from the script. This can be accomplished if each individual module loads in a pull-requirements fashion,
that is it self-loads any required modules.
That way and with proper partition of library code to modules it is possible to build Avisynth libraries of any
complexity while not inducing performance penalties to scripts needing only a small subset of the library's
functionality.
For anything that is not been covered by this tutorial, see the loader module functions' documentation as well as
the AVSLib's source code for details and working examples.

Module internals
Each module in order to register with the loader module must declare its name and position in the library's
hierarchy. This is accomplished by the use of the DefineModule "macro", typically as the first line in the module's
script file (it is called a macro because it is designed to be called without been assigned to a variable - it returns
last).
What the DefineModule "macro" does is to create a unique global variable and assign true to it. Three string
arguments must be supplied to it:
• The name of the library that the module belongs to.
• The name of the package / subpackage that the module belongs to.
• The name of the module itself.
The same arguments must be supplied to LoadModule, in order for the module to be actually loaded (imported) at
the main script.
What LoadModule does is to check whether the global variable associated with the module is defined. If it is
defined then it is assumed that the module is already loaded and no operation is executed; else a proper Import
statement is executed to load the module.
The convention followed by the loader routines to determine the path of the module's script file is briefly
presented below:
• The library name determines the root folder where the library's components are installed.
The library must install in Avisynth's plugins folder a file that declares a string constant with name
__LIBROOT_{library name} and value the path to the library's root folder.
That file should also declare any configuration constants recognised by the library (see the LoadLibrary
documentation for details).
• The package / subpackage name is a relative path (from library's root folder) to the folder where the
package's modules are located.
Multiple levels of hierarchy are allowed through the use of the "/" (slash) character. Each part of the path
following a "/" is considered a subfolder of the folder determined by the part of the path preceeding the
"/".
• The module name is the name of the module's script file without the extension (which is assumed to
always be ".avsi").
In addition, each module must explicitly (if a pull-requirements loading fashion is selected as is the case with
AVSLib) load any modules that is depended to. This is typically executed at the next lines of the module's script
after the call to DefineModule.
In order not to mess with user scripts the load calls should assign their return value to a dummy variable (so that
they not override the last special variable).
Because loading a bunch of modules to satisfy dependencies tends to produce an ugly block of consecutive
assignments, it is recommended to group them inside triply doublequoted multiline strings which are passed to
Eval standard Avisynth function, as in the following example:
DefineModule("avslib", "string", "sprintf")
global __load__ = Eval("""
LoadModule("avslib", "base", "core")
LoadModule("avslib", "numeric", "core")
""")
global __load__ = IsPackageLoaded("avslib", "string") ? NOP : Eval("""
LoadModule("avslib", "string", "core")
LoadModule("avslib", "string", "search")
""")
global __load__ = IsPackageLoaded("avslib", "array") ? NOP : Eval("""
LoadModule("avslib", "array", "core")
LoadModule("avslib", "array", "slices")
LoadModule("avslib", "array", "operators")
LoadModule("avslib", "array", "transforms")
""")

The IsPackageLoaded and IsModuleLoaded test functions are used to determine if a package or module is
already loaded to leave the corresponding block with a NOP if the later is true instead of executing a block of
function calls.

Package internals
Packages are declared and loaded with similar to modules mechanisms. Since however they are a collection of
modules, there are some specific requirements that must be fulfiled.
Each package is declared in a special .avsi file (__init.avsi) contained at the same folder as the modules (and / or
subpackages) that belong to the package.
In order to register with the loader module the package must declare its name and position in the library's
hierarchy. This is accomplished by the use of the DefinePackage "macro", typically at the first line in the
package's special script file (it is called a macro because it is designed to be called without been assigned to a
variable - it returns last).
The only other thing that the package's script file has to do is to load all modules of the package (remember,
dependencies fulfilment has been assigned to modules).
In order not to mess with user scripts the load calls should assign their return value to a dummy variable (so that
they not override the last special variable).
Because loading a bunch of modules tends to produce an ugly block of consecutive assignments, it is
recommended to group them inside triply doublequoted multiline strings which are passed to Eval standard
Avisynth function, as in the following example:
DefinePackage("avslib", "numeric")
global __load__ = Eval("""
LoadModule("avslib", "numeric", "core")
LoadModule("avslib", "numeric", "rounding")
LoadModule("avslib", "numeric", "powseries")
LoadModule("avslib", "numeric", "functions")
LoadModule("avslib", "numeric", "statistics")
LoadModule("avslib", "numeric", "curves2d")
""")

Library internals
In order for a library to cooperate with the loader, it must follow the general structure anticipated by the loader's
routines (see the two sections above). In addition it must provide two script (.avsi) files:
• An .avsi file (__init.avsi) contained at the root folder of the library that loads the various configurations
of the library based on the value of the __LIBCONFIG global variable.
This is the file that will be called by LoadLibrary; the later will assign to __LIBCONFIG the value
passed as the second argument to LoadLibrary.
• A special .avsi file that must be installed in Avisynth's plugins folder that declares a string constant with
name __LIBROOT_{library name} and value the path to the library's root folder.
That file should also declare any configuration constants recognised by the library. Those are the values
that are passed as the second argument to LoadLibrary.
An example of a library's __init.avsi is presented below (taken from AVSLib version 1.1.0):
global __load__ = \
__LIBCONFIG == CONFIG_AVSLIB_FULL ? Eval("""
LoadPackage("avslib", "base")
LoadPackage("avslib", "numeric")
LoadPackage("avslib", "bool")
LoadPackage("avslib", "string")
LoadPackage("avslib", "array")
LoadPackage("avslib", "clip")
LoadPackage("avslib", "debug")
LoadPackage("avslib", "filters")
""") : ( \
__LIBCONFIG == CONFIG_AVSLIB_SCRIPT ? Eval("""
LoadPackage("avslib", "base")
LoadPackage("avslib", "numeric")
LoadPackage("avslib", "string")
LoadPackage("avslib", "debug")
""") : ( \
__LIBCONFIG == CONFIG_AVSLIB_ARRAYS ? Eval("""
LoadPackage("avslib", "array")
""") : ( \
__LIBCONFIG == CONFIG_AVSLIB_FILTERS ? Eval("""
LoadPackage("avslib", "clip")
LoadPackage("avslib", "filters")
""") \
: Assert(false, \
"AVSLib: 'config' argument out of accepted range") )))

The last line of the if..elseif..else construct presented above throws an error if the user pass in an invalid
configuration argument. Another approach that one might wanted to follow is to silently load the entire library if
an out-of-range configuration value is passed in.
An example of a library's declaration file that is copied to Avisynth plugins folder is presented below (taken again
from AVSLib version 1.1.0):
# LoadLibrary configuration constants
# zero should always be reserved for full loading
global CONFIG_AVSLIB_FULL = 0
global CONFIG_AVSLIB_SCRIPT = 1
global CONFIG_AVSLIB_ARRAYS = 2
global CONFIG_AVSLIB_FILTERS = 3

# this will be filled by the setup program upon installation


global __LIBROOT_AVSLIB = "path_to_the_library_root_folder"

The names of the global constants are arbitrary; nevertheless a sound convention such as the one presented above
(in particular the use of library's name inside the constants' names) is useful to avoid name clashes with other
libraries.
Library organisation
The organisation of the library is up to the developer; the only restrictions (a sum up of the previous sections)
imposed by the loader are the following:
• There must be at least one package (a good name for small libraries is "base" or "core").
• The name of the folder containing a package must be the same with the visible to user name of the
package. The same is true for modules also.
• All visible to the user modules of the package (ie those that LoadModule can be called to load them)
must be inside the containing package's folder (utility files that are loaded by the module such as other
script files or plugins need not).
• All visible to the user packages of the library (ie those that LoadPackage can be called to load them)
must be inside the containing library's folder (utility files - see above - need not).
• Plugins cannot be loaded directly; a thin wrapper module is required (this is intentional, since one of the
purposes was to present to the user a single interface for loading anything).
• All script files visible to the user (ie packages, modules and special __init.avsi files) must have the
extension .avsi.

Você também pode gostar