ASCII Antics

Simulating a manual typewriter was examined in an earlier chapter.

The techniques in that chapter are not really useful for simulating typing on a computer or other electronic device. This is because Text cues in QLab automatically keep the text vertically centered as new lines are added. With the typewriter simulation the text position can be adjusted easily at the end of each line, because a manual typewriter raises each line of text with the action of the carriage return lever. When typing on a computer, generally the top line remains static and each line of text appears beneath the previous one (at least until the screen needs to scroll because it is full.)

This tutorial uses a method in which the entire text to be typed is always contained in the Text cue, laid out exactly as required, including the application of any variations in font, size or style.

Before being displayed, the alpha channel of the text is set to 0 making the text invisible. Then each character’s alpha channel is reset to 1 sequentially, at a rate that can be set by the user, revealing the text one character at a time. The examples in this chapter are programmed in QLab 5, but the same method works in QLab 4. Downloadable examples are provided for both QLab 4 and QLab 5.

Here it is in action:

In the demo workspace, there is a single Timeline Group cue, numbered “TTY”, which contains all the cues that enable the typing to be controlled. This group contains Memo cues, which store parameters in their post-wait or name properties and a Script cue, which controls the process.

Cue “TTY” is in a separate cue list named “TYPE” together with the Text cues to be used.

In the main cue list are a series of Timeline Group cues, which would normally be inserted where required in a cue list with more conventional cues.

Each of these Group cues contains three Network cues which send information to the cues in Timeline Group cue “TRIG” to select:

  • The Text cue that will be typed.
  • The speed of the typing
  • The variation in the interval between characters appearing, which is used to humanize the typing when we want it to appear that we are watching a human typing the text in real time.

The Group cues also contain a Start cue which starts cue “TTY” to start the typing.

In the demo video, the first cue in the main cue list simulates the typing of a picture of an Apple II computer as retro ASCII art.

This is followed by a block of text describing the Apple II computer, typed in a font which closely resembles that used by the the original Apple II. This font is Print Char 21 from KreativeKorp and is included in the downloads. The font can be installed by double clicking the file PrintChar21.ttf and then clicking the Install Font button.

Installing the font

An alternative font is also included, PRNumber3.ttf, which is a narrower version.

The image and the text then scroll off the screen.

The next cue simulates the typing of the QLab 4 logo as ASCII art.

The remaining cues in the video demonstrate that as well as being useful for simulating the displays of retro computers, more modern typefaces, layouts, and colors can be used to simulate phones, tablets and recent computers and, of course, the way that ChatGPT outputs its generated replies to user prompts.

How It Works

Cue “TTY” has its If running, a second trigger… parameter set to hard stops & restarts

Second trigger action

This allows all the parameters of the typing to be changed without explicitly stopping and starting the Group cue using Start and Stop cues. In the demo, this is utilized when a new cue types below the text from a previous cue.

The Memo cue numbered “QNUM” stores the number of the Text cue to be typed as its cue name.

The Memo cue numbered “CPS” stores the speed of the typing as its post-wait. This is the nominal number of characters per second to be typed.

The post-wait time of the Memo cue numbered “VAR” stores the desired variation in the time between consecutive characters.

The Script cue contains this script which is based on a script by Brent Lord:

tell application id "com.figure53.QLab.5" to tell front workspace -- change to "com.figure53.QLab.4" for QLab 4
	try
		set theCue to cue (q list name of cue "QNUM" as text)
	on error
		display alert "Cue " & (q list name of cue "VAR" as text) & " does not exist!" giving up after 3
		return
	end try
	set theFormat to {rgbaColor:{red:1, green:1, blue:1, alpha:0}}
	set live text format of theCue to theFormat
	set theCount to count of characters of (text of theCue as text)
	start theCue
	set theCurrentFormat to rgbaColor of item 1 of (get text format of theCue)
	set theFormat to {rgbaColor:{red:red of theCurrentFormat, green:green of theCurrentFormat, blue:blue of theCurrentFormat, alpha:1.0}, range:{rangeOffset:1, rangeLength:0}}
	set thisLength to 1
	repeat theCount times
		set theCharactersPerSecond to post wait of cue "CPS"
		if theCharactersPerSecond > 1000 then set theCharactersPerSecond to 1000
		set theVariation to post wait of cue "VAR" -- variation in gap between characters in seconds
		
		set rangeLength of range of theFormat to thisLength
		set live text format of theCue to theFormat
		set thisLength to thisLength + 1
		set theDelay to (1 / theCharactersPerSecond) + (random number from 0 to theVariation)
		delay theDelay
	end repeat
end tell

The script begins by trying to grabbing the post-wait of the Memo cue numbered “QNUM” and placing it a variable, theCue. If a cue with that cue number does not exist in the workspace, the error causes an alert message to be displayed which can either be cleared by the user, or will disappear automatically after the ‘giving up’ time (three seconds in the demo.)

The script then sets a variable, theFormat, to a text format record that will make the text invisible by setting its rgbaColor alpha value to 0. The Text cue that is about to be started has its live text set to that format. Setting the live text format of a cue is temporary, it does not affect the stored text format, and the change isn’t put on the undo stack.

The characters in the Text cue are counted to set the number of times the repeat loop in the script will execute, and the cue is started.

A variable, theCurrentFormat is set to the rgbaColor of the text format record of the first character of the text. Then, theFormat is set to that same color, but with the alpha set to 1. This means that we now have an rgbaColor record which we can use to set the color of each character to be the same color as the first character of the text in the Text cue. By setting the alpha to 1, we make the character visible.

The repeat loop gets the typing speed and variation values from the Memo cues storing them. This is done inside the repeat loop so that it is possible to change speeds as the typing is taking place. In the demo video, the final typing is sped up and slowed down using Network cues with OSC fades like this one:

OSC fade

Here, the typing is accelerated by fading the value stored in the post-wait of cue “CPS” from 20 to 10000.

The number of characters that the formatting is applied to is set by changing the value of the range length of the text format record. This is incremented by 1 each time the loop repeats, setting one more character to an alpha of 1.

The repeat loop is delayed by a time calculated from the characters per second value with the addition of a random time between 0 and the variation value. This delay constitutes the time between one character being typed and the next. In practice, regardless of these settings, there will be a limit to the number of characters that can be typed per second, dependent on the speed of the computer used.

The repeat loop continues until all the characters in the text are processed.

All text in demo examples generated in chatGPT.

Fonts in demo and in downloads by KreativeKorp, distributed under a free license.

Chapter image ASCII art of QLab 4 logo. The QLab 4 logo is a trademark of Figure 53, LLC.