# SSATool 4.3

## Purpose

To automate the creation and manipulation of Advanced Substation Alpha files.

## Functions

Shifting
SSATool can shift a file by entering a time (hour:minutes:seconds.subseconds), by a given number of frames, or by specifying an 'old' time and the new time that it should be shifted to. Shifting by time or frames require a given direction, while time difference already has a direction, given the 2 times.

#### Shifting options

- Shift Start/End times: You may choose to only shift the start or end times of each line.
- Replace negative times: If you're shifting backwards and some times end up negative, this option will replace them with a 0 time. After all, who wants to see subtitles before you even watch the video?

Commands
These are parameterless functions that don't take much explaining.

- Strip SSA: Strips all SSA code except for \k,\K,\kf,\ko. Useful for when you want to undo typesetting to a file but keep the timing.
- Removes duplicate dialogue lines. If you've got a file that used layer per syllable type karaoke and you strip SSA, you'll have several duplicate lines.
- Change last \k based on line length: Goes through dialog lines, and adjusts the length of the last syllable to match the length of the line. It is possible for this value to turn out negative if the timing is way off, so use it with care.

Length-based \k or \K
This changes each syllable to \k or \K as determined by a threshold.

- Threshold: Anything above or equal to this gets changed to \K and anything under it uses \k.

Scale Resolution
SSATool can change a resolution of a SSA file for you. If you have two different files that you want to merge, but they have different resolutions, then you must use a function like this.

#### Scaling options

- Scale factor: Pretty straightforwardly, the amount that you want to scale by.
- Scale PlayRes: Scale PlayResX/PlayResY in the header, if they're already there. They must be checked for this to do anything.

#### Scaled Parameters

- Style lines: Font size, outline, shadow, margins
- Dialogue lines: Margin overrides
- \bord: using Y scale
- \clip: using X and Y scales
- \fs: using Y scale
- \fsp: using X scale
- \move: using X and Y scales
- \org: using X and Y scales
- \p: Coordinates will be scaled with X and Y scales. If a \p1 is in a \clip, it DOES continue past the clip unless you \p0.
- \pbo: using Y scale
- \pos: using X and Y scales
- \shad: using Y scale

Lead-in/out
This adds a lead-in/out to lines. It can add a \k to the beginning of the line to compensate. It does not current affect other tags like \t, \move, etc.

#### Options

- In Time: If checked, this is the amount of lead-in time. If it's a number, it's interpreted as seconds. Else it's interpreted as a timecode.
- Out Time: If checked, this is the amount of lead-out time. If it's a number, it's interpreted as seconds. Else it's interpreted as a timecode.
- Affect only karaoke lines: Affect only lines with \k in them if checked.
- Add empty \k for karaoke: Add a \k to compensate for lead-in time to lines that have \k in them already.

Gradient Maker
This will create a gradient by making several lines using clip. You may type text in, or you may select a line from the loaded file and click "Copy Selected List Item to Input." If the line has dialogue: ... in it (IE the information for the line and not just the line itself), then select that and click the "Move Selected" button next to the "Before Grad." textbox. This will place that text before each line without actually putting it in the gradient. Fill in the boxes and click Create.

### Options:

- Before Gradient: This is text that doesn't get gradiented. Put all the Dialogue: ... stuff here. This is easily accomplished by highlighting the appropriate text in the "Gradient Text" field and clicking the "Move Selected" button.
- Clip Lines: How many lines the gradient will span. More lines is more precise.
- Start/End Pos: The start and end positions in coordinate form x,y. Only include the part that will increase, IE if you want to go across a 640x480 screen horizontally, only x should be increasing here, and the height of 480 is an offset (it's always there), so leave height 0 here.
- Offset: Static values that are added to the second X and Y positions. See the above example, where the offset here would be 0,480.
- Start/End Value: The start and end colors in (A)BGR form. They can be in decimal form or in hex form with leading H. Do not include ampersands. Alpha is optional (as denoted by the parenthesis).
- Linear/Log/Exp grad: These control how the colors are scaled: linearly, logarithmically, or exponentially (base^ratio). If you use one of the latter two, set the base to something greater than 1.
- Turnaround: This will allow you to go from the start value to the end value somewhere in the middle of the gradient, and then back to start RGB. It's a percentage. At 50%, it will turn around at the halfway point.

Blur
This allows you to use layered alpha blurring. Make sure your input does not have a \bord or \pos coordinate in it, unless you're doing a glow, which does allow \pos. Also, if your line has dialogue: ... in it, make sure to select that part of the line and click the "Move Selected" button next to the "Before Blur" textbox.

### Options:

- Before Blur: This is text that doesn't get blurred. Put all the Dialogue: ... stuff here. This is easily accomplished by highlighting the appropriate text in the "Blur Text" field and clicking the "Move Selected" button.
- Type: This allows you to select "true blur" or glow. True blur will move the line around with different alpha values given a position of the text. Glow will just leave the text in the same spot while creating subsequently larger borders with more alpha.
- Lines: Only used with glow option. Creates the given amount of lines where each line has a larger border than the last.
- Start/End alpha: Start and end alpha values. Decimal or hex with leading H. Omit the ampersands.
- Blur Radius: How many pixels the blur should be.
- Position: Only needed for true blur: The position on the screen where the text is in x,y form. Pixels will be added/subtracted to this value.
- Linear/Log/Exp blur: These control how the alpha values are scaled: linearly, logarithmically, or exponentially (base^ratio). If you use one of the latter two, set the base to something greater than 1.
- Affect: Will blur the selected elements (\1c, \2c, \3c, and/or \4c). Not applicable to glow.
- On subsequent lines...: If not blurred, the elements selected here will have &HFF& alpha values for all lines except the main line.

Notebox Maker
This allows you to easily create cool looking noteboxes from templates contained in the included XML file. Noteboxes can be one or two lines long and each template must specifically give code for each length. See the included file for an example. Templates may be of different resolutions. If a script is loaded which contains PlayResX and/or PlayResY, the generated notebox will be automatically resampled to the script size. Otherwise, the generated notebox will be at the default resolution of the template.

### Options:

- Copy styles to file: The styles for the notebox will not be inserted into your file just by generation of a notebox. You can use this button to insert them automatically in that case.

Error Checker
This will check a file for some common errors. It checks dialogue and style lines.

#### Checks for:

- Unopened/unclosed parenthesis
- Unopened/unclosed brackets
- No trailing ampersand in color/alpha values
- Lowercase H for hex
- Malformed transformations (\t(time,time)\effect)
- Decimals without leading integers (.01 vs. 0.01)

Font Test
This will search a file for all fonts used and check if they are installed on your system. If fonts are not installed, you may search a directory for the fonts. It does not make sure the files it finds have the needed styles. It only matches by font name.
Manual Transform
How many times have you wished you could use \t on something that doesn't allow it? How many times have you wanted a nonlinear acceleration parameter for \move? Here's a function that will automatically interpolate these things like \t, but it's much more powerful.

### Zones/the Times Listbox

Manual Transform is based on zones, which are made up of a start and end time. There must be at least one zone. Each additional zone uses the end time of the previous zone as its start time. So if you entered the times of 0:00:00.00, 0:01:00.00 and 0:02:00.00, there are two zones: one from 0:00:00.00-0:01:00.00 and one from 0:01.00.00-0:02:00.00.

Based on these different zones, you can have variables which can scale differently at different times. Numbers can scale linearly during one zone and exponentially during another if you like. Text can change between zones.

If this flexibility is not required, just entering a start time and an end time, making one zone only, will keep things simple.

### Variables

This is the data that gets scaled. To add a variable, click the new button and type a name into the popup. You can then edit the values for each time by clicking on the appropriate field in the variable list. You may use either a string or a number. Numbers will be scaled automatically, whereas strings will switch over when a new zone is reached.

If you enter a string and a number under the same variable, then it will treat both as a string. If you have a string and a number and a number (2 zones), it will print the string until it hits the second zone, where it will then scale between the two numbers. That is to say that if, in the current zone, the start and end variable values are both numbers, the number will be scaled; If one or both are non-numbers, both will be treated as strings.

Acceleration: You can use linear, logarithmic or exponential acceleration for each variable and zone. Exponential acceleration has 2 forms: ratio^base, which is specified by just entering a number > 1, or base^ratio by specifying expbase (Example: exp2). Specify a log transform by typing logbase. If none of these are specified or are incorrectly entered, a linear transform will be used. ASSA itself uses ratio^base for acceleration, so the default behavior (entering a number) works the same as entering that number into \t.

### Other options

- Code is how SSATool puts the variables together to form the text that gets output. To add the line times, use %starttime% and %endtime% in the code. To use a variable in the code, surround the variable name with percentage signs. You may use scripting functions here. If you're scaling an integer, you're going to want to round it with scripting because it will be printed as a decimal otherwise.
- Times: Enter the times for this to span. You must enter at least two times. You may enter more than one time to create different zones where variables can be scaled differently. Times should be the first thing you add.
- Frame Rate: The framerate of the video. All entered and output times will be snapped to the nearest frame.

Kanji timing
This function will allow you to time Kanji (or pretty much any other East Asian character set) from Roman letters. You may combine \k times, but this function can't work with \t as it can't be sure how to handle the times. It could also technically be used in reverse, but it's not capable of splitting syllables from the source style.
You must have your two character sets entered in different styles. The kanji may already be timed, but those times will be overridden if so. Empty syllables will be copied alone, or will be combined with the surrounding syllables if those are to be combined.

### Options

- Styles: Select your source and destination styles here. The source style will be used for times and all ASSA code. Destination lines will be overwritten in the list. Note: Any ASSA code appearing before the \k will be directly copied, and ASSA code after the \k is currently not copied at all.
- Start: Brings the first lines of each style into the corresponding text fields.
- Link: When you have selected corresponding syllables, this will pair them up and you will see them appear in the group list.
- Unlink last: If you've made a mistake, this will unlink the last pair. You may use it as many times as needed.
- Skip source line: Skip the current source line.
- Skip destination line: Skip the current destination line. It won't be modified at all.
- Go back a line: Goes back to the last line for both the source and destination. It does not undo any changes made, but you may redo it.
- Accept line: When all of the grouping for a line is finished, this will modify the line in the list and automatically load the next lines for source and destination.

### Keyboard shortcuts

Don't use the mouse to highlight grouping. If you incorrectly try to split syllables from the source, the function won't work right, so please use the following keyboard shortcuts while the destination textbox has focus. They're much faster.

- Right/left arrows: Select more or less text from the destination, respectively.
- Up/down arrows: Select more or less text from the source, respectively. The source text is locked so it can not be split, but you may combine syllables from it.
- Enter: Link the selected text, or if all text is linked, accept the line and move on to the next.
- Backspace: Undo the previous linked text.

Karaoke effects
The karaoke effect generator is a complex karaoke effects automator. In simple terms, it could be called a "\k to \t converter," though it is not limited to transformations. You have several variables (listed below) and scripting functions (listed further below in another section) available to use in template effects. You also have "raw code," which will just dump anything you put in there into the SSA. You can use variables in any of the effect fields. You may use raw code to accomplish anything that the other effects can do. Other effect templates are there just to make it easier for you to make presets. There's an effects editor to add your own presets available under the Effects menu.

### Layers

Layers are the basis of the effects system. They are, in essence, one of the base elements of ASSA itself. The simplest implementation of a layer is a single dialogue line. That's it. The subtitler program reads each line and decides where each line goes, and in what order they go.

However, in SSATool, layers are different than how SSA itself looks at them. A layer is how SSATool processes a line in order to add effects. Depending on the complexity of an effect, it may take from one to several lines to accomplish. That is, you might have two or three or even dozens of dialogue lines composing what we see as one line! So each layer in SSATool will add another dialogue line with the same text but potentially different overrides. But to make things even more confusing, there's an exception: Layer-Per-Syllable. What happens if you want to do something to a syllable in a karaoke as its "turn" comes up, but the command to do what you want to do is a command that affects the whole dialogue line, even if you use \r? You often have to make a dialogue line corresponding to each syllable.

This is what layer-per-syllable does. It will dynamically create a new dialogue line (layer) for each syllable. You're typically going to want to see each line only for the syllable it corresponds to, because that's the basic reason why layer-per-syllable exists. To accomplish that, you're going to want to have a couple of effects in addition to your transformation code. These extra effects will be to make the line invisible except at the corresponding syllable. You'll use conditions (explained below) to apply alpha codes before and after this syllable. A sample layer-per-syllable project file should be bundled to show you how to go about it. Don't use it as a basis every time you want to do layer-per-syllable, because it will ensure that you don't understand how the process works. To make karaoke, you must first understand how ASSA renders karaoke.

To enable layer-per-syllable mode, simply add a layer and make sure the Layer-per-Syllable checkbox is clicked. You may combine layer-per-syllable layers together or with fixed layers if you like.

### Conditions

There are two types of conditions in the karaoke effects generator: effect conditions and layer conditions. They both do the same thing, but they work on a different scope. For both, you enter two things to compare. These things may be numbers or strings, and you may use variables and scripting functions (listed below).

- With effect conditions, each condition must be true for that effect to be applied, or it will just be skipped for that syllable. There is no condition checking for effects on a per-line scope, meaning the conditions are only checked per syllable, not per line. This is the more flexible option of the two.
- With layer conditions, each of these must work out for all of the effects in that layer to be applied. By default, if this is not met, there will be no dialogue line created at all. However, when you create your layer conditions, you may option to create the dialogue line WITHOUT effects if the conditions are not met. For fixed layers, the option is called, "Add line unchanged if layer conditions not met." If you're using layer-per-syllable, just that option will add the line several times (once per syllable) if the layer conditions aren't met, so you'll also want to enable the option, "Only add it once."

### Layout

The layout of the karaoke effects section can be a little confusing at first. At the left, there's a treeview. This holds information about all layers and effects. You can add a layer via the button under it. Once you have added and selected a layer, you may add effects to it through that button. You may drag items around the treeview to reorder them or to move effects to a different layer. You may duplicate or remove layers or effects through the corresponding buttons.

When you select a layer in the treeview, the layer options page automatically shows up. Here, you can add layer conditions or change the options for the layer. When you click on an effect, you get a tabbed setup where you can view the options for that effect or the conditions. To change an option for an effect, just click on the corresponding field.

### Options

- Don't add the syllable text: This will leave out the actual text for the syllable. You may add it yourself in your effects using the %text% variable. This allows you to split a \k if you like.
- Remove \k: This will remove \k, \K, \ko and \kf after applying effects. Keep a backup file before you use this option in case timing needs to be changed later.
- Add line unchanged if conditions not met: If layer conditions aren't met, add the dialogue line with no effects. You could get missing dialogue lines without this option.
- Only add it once: An extension of the above for layer-per-syllable mode to prevent dialogue lines from being added multiple times when layer conditions are not met.
- Layer-per-Syllable: Enable Layer-per-Syllable mode for this layer. See the explanation above.
- Repetitions: This only applies to non-LPS layers. The layer will be repeated this amount of times. It only applies to karaoke lines, not regular dialogue lines.

### Karaoke variables

%karastart% | Start time of current kara block in milliseconds.
%karastart[n]% | Start time of kara block n in milliseconds. Yes, the square brackets should be there. You may use other variables in the brackets (except for another variable with brackets). Example: %karastart[%totkaranum%]%
%karaend% | End time of current kara block in milliseconds.
%karaend[n]% | End time of kara block n in milliseconds. Yes, the square brackets should be there. You may use other variables in the brackets (except for another variable with brackets).
%karamid% | Mid point of current kara block in milliseconds. ((start+end)/2)
%karalen% | Length of current kara block in milliseconds.
%karalen[n]% | Length of kara block n in milliseconds. Yes, the square brackets should be there. You may use other variables in the brackets (except for another variable with brackets.
%karanum% | The number of the kara block being evaluated, indexed from 0.
%karanumtot% | The total number of kara blocks in this line. If you compare with %karanum%, make sure to add 1 to %karanum% since it starts at 0.
%linestart% | Start time of current line in seconds in seconds
%lineend% | End time of current line in seconds
%linelen% | Length of current line in seconds
%layernum% | The current layer number, indexed from 0.
%layernumtot% | The total number of layers
%layernumlps% | The current layer number in layer-per-syllable mode. In fixed layer mode, this is also also used when repetitions of the layer is set > 1. Indexed from 0.
%layernumlpstot% | The total number of layers in layer-per-syllable mode. In fixed layer mode, it is the total number of repetitions of the current layer.
%name% | The name (SSA) or actor (ASS) of the line.
%style% | The name of the current style
%text% | The text inside of the current syllable. Recommended for use with "Don't add the syllable text itself" in the Layer Conditions+Options tab, but can be used by itself.

Scripting

#### Functions

$eval(expression) | Does math/logic. It supports the sub-functions listed in the table below. Strings used in this must be surrounded by double quotes. Not using quotes should work in most situations, but this is mostly for reasons of backwards compatibility. If used for logic, it will return True or False (as booleans, so no quotes around them).
$iif(expression,t, f) | Inline if (a conditional statement). The expression may be a boolean logic expression, or it may be something that evaluates to true or false. If the expression is True, it returns the second argument. If it's false, it returns the third. If it (or you) messes up, it returns "error".
$len(text) | Returns the length of text.
$left(text,length) | Returns the first length characters of text.
$listindex(n,item,item,...) | Returns the nth supplied item indexed from 1. Returns "error" if the supplied value is incorrect.
$listindexlast(item,item,item,...) | Returns the nth supplied item indexed from 1. Returns "error" if the supplied value is less than one. Returns the last value if the index is too big.
$listindexwrap(item,item,item,...) | Returns the nth supplied item indexed from 1. Returns "error" if the supplied value is less than one. Wraps around to the beginning of the list if the index is too big.
$mid(text,start,length) | Returns length characters of text, starting at start. The first character is indexed as 0.
$randlist(item,item,item,...) | Returns a random item from the given inputs.
$right(text,length) | Returns the last length characters of text.
$str(text,n) | Repeats text n times.

#### Eval Sub-Functions

abs | Return the absolute value of a number.
acos | Returns the arc-cosine of a number.
asin | Returns the arc-sin of a number.
atan | Returns the arc-tangent of a number given an angle.
atan2 | Returns the arc-tangent of a coordinate. Format: atan2(x,y)
bound | Bounds a number between 2 values. Takes 3 parameters: Number, LBound, UBound. Returns LBound if Number < LBound, or UBound if Number > UBound. Otherwise returns Number.
ceil | Rounds up. Example: ceil(5.01) returns 6
cos | Return the cosine of a number.
fact | Computes the factorial of an integer. This is the same as the ! operator.
floor | Rounds down. Example: floor(5.99) returns 5. floor(-5.99) returns -6.
int | Returns the integer of a number. int(-5.99) returns -5.
len | Returns the length of a string.
log | Return the log of a number. It's base e. If you want a different base, do log(number)/log(base)
max | Return the higher of 2 numbers.
min | Return the lower of 2 numbers.
rand | Returns a bounded random integer. rand() gives you an integer from 0 to 1, rand(maxvalue) gives an integerfrom 0 to maxvalue, and rand(low,high) from low to high
randf | Returns a bounded double precision floating point number. randf() gives you a double from 0 to 1, randf(maxvalue) gives a double from 0 to maxvalue, and randf(low,high) from low to high
round | Rounds a number to the given number of decimal places. Format: round(number,decimal places)
sin | Return the sin of a number.
sqrt | Return the square root of a number.
tan | Return the tangent of a number.

Take note that these do NOT have a leading $ like the above functions. They must be used INSIDE of $eval.

#### Data types supported by eval

Boolean | true or false. Capitalization does not matter. Do not enclose in quotes.
Integer | Support not done, numbers currently treated as double. All mathematical/bitwise operations are available.
Double | Double-precision floating point number. All mathematical operations except modulus are available.
Point | An x,y pair. You may add or subtract points, or you may add, subtract, multiply or divide points by scalars. Not finished.
String | A string. + may be used to concatenate strings. All strings MUST be enclosed by quotes.

Boolean logic comparisons are available with all types. Also, note that conditions in the karaoke effects tool internally use $eval, so strings must be enclosed in quotes in there. Variables that are strings currently do NOT automatically do so.

#### Constants supported by eval

e | e, the natural logarithmic base.
g | The golden ratio.
Pi | Pi.
y | Euler's constant.

All numerical constants are double precision (64-bit) floating points.

#### Mathematical/Bitwise operators

+ | Add
- | Subtract
* | Multiply
/ | Divide
! | Factorial
% | Modulus (remainder after integer division)
& | Bitwise and
\ | Bitwise or
\ | Bitwise xor
<< | Shift left
>> | Shift right
~ | Inversion

#### Boolean/comparison operators

= | Equal to (if used with text, is case insensitive)
<> | Equal to (if used with text, is case sensitive)
== | Equal to (if used with text, is case sensitive)
!= | Not equal to (if used with text, is case insensitive)
!= | Not equal to (if used with text, is case sensitive)
> | Greater than
>= | Greater than or equal to
< | Less than
<= | Less than or equal to
|| | Boolean or
&& | Boolean and

Effect and project files

### Effect files

Effect files are XML files that hold all preset effects except for "raw code," which is built in. They use the extension exml. You may edit them in a text editor by using the bundled effects as a template. There's also an effects editor in the program to write them for you.

### Project files

Project files are also XML files, but they are in a different format than the effect files. They contain all layer, filter and condition information as well as the filename to the loaded SSA, if applicable. They are not a script - they do not keep track of your commands, but merely karaoke effects information. They may be edited in a text editor, but I only recommend doing that if you want to make a slight modification to an existing file.
File Encoding
SSATool will open most common file encodings including ANSI (using your local codepage), Shift-JIS, and Unicode in 1, 2, or 4 octet versions. Some encodings, such as Shift-JIS are notoriously hard to detect, so if your file includes Japanese text and you're unsure of the encoding, please make sure to find out, or that it displays correctly if you use the open file option without the SJIS.
As of version 4.1, SSATool employs extremely simple algorithms for attempting to detect Shift-JIS and EUC-JP. If a file is under 4KB, 100 or more characters detected with either encoding will trigger a prompt asking to reload using that encoding. If the file is 4KB-8KB, the threshold is 300, and if the file is 8KB or more, 600.
Thanks
The following are people I want to thank for helping me with this, be that by testing, lending me webspace, putting up educational code samples on the web, etc. Some will be in names, and others will be in online nicknames.

- DeathWolf - testing, feature suggestions, webspace
- Neil Davidson - the save file dialog w/ encoding I'm using
- PovRayMan - icon
- SCR512 - testing
- zalas - feature suggestions
- Dead-Cow - testing
- Nikolai - testing, feature suggestions
- Anyone else I forgot

SSATool is copyright (C) 2005-2006 Dan Donovan. It is free to use.